我创建了一个下载 CSV 文件的函数。我将使用它来下载简单的报告。我在使用 Wildfly 和 JAX RS 的 Netbeans 上遇到以下错误
RESTEASY002005: Failed executing POST /reports/downloadCSV/: org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: java.io.FileWriter of media type: application/octet-stream
这是我的代码:
Controller
ParametersClass 更新
@POST
@Path("/downloadCSV")
@Produces("application/octet-stream")
public Response downloadCSV(ParametersClass param) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
FileWriter fileWriter = null;
Date date = new Date();
try {
fileWriter = new FileWriter("MainReport_"+dateFormat.format(date)+".csv");
fileWriter.append(csvService.mainReport(dateFormat.parse(param.getStartDate()),dateFormat.parse(param.getEndDate())));
fileWriter.flush();
fileWriter.close();
ResponseBuilder response = Response.ok((Object) fileWriter);
response.header("Content-Disposition","attachment; filename=\"MainReport_"+dateFormat.format(date)+".csv\"");
return response.build();
} catch (ParseException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
csvService
返回如下字符串:
Column1,column2,column3
cellInfo1,cellInfo2,cellInfo3
,cellInfo2,cellInfo3
cellInfo1,,cellInfo3
cellInfo1,cellInfo2,
,,cellInfo3
我尝试使用不同的 @Produces
=> @Produces('text/csv')
, @Produces('application/octet-stream')
如果我删除注释 @Produces
我会收到以下错误:
RESTEASY002010: Failed to execute: javax.ws.rs.NotSupportedException: RESTEASY003200: Could not find message body reader for type: class com.xo.CSVFile of content type: application/x-www-form-urlencoded;charset=UTF-8
AJAX
var dateRange = new Object();
dateRange.startDate = '2017-07-20';
dateRange.endDate = '2017-08-10';
$.ajax({
type: 'POST',
url: appPath + '/api/reports/downloadCSV/',
data: JSON.stringify(dateRange),
async:true,
success: function(data) {
}
});
我做错了什么?你能帮帮我吗?
.
解决方案 感谢@albert-bos
第一。检查下面来自@albert-bos 的解决方案中的链接。
第二:检查this也有链接
第三:
Controller :
@POST
@Path("/downloadCSV")
@Produces("text/csv")
public List<LinkedHashMap<String, String>> downloadCSV(ParametersClass param) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
return csvService.mainReport(dateFormat.parse(param.getStartDate()),dateFormat.parse(param.getEndDate()));
} catch (ParseException ex) {
return null;
}
}
MessageBodyWriter:
我创建了一个名为 CSVMessageBodyWritter 的类(检查链接),但我修改了方法 writeTo
:
@Override
public void writeTo(Object t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
CsvSchema schema = null;
CsvSchema.Builder schemaBuilder = CsvSchema.builder();
if(t!=null){
List<LinkedHashMap<String, String>> reportArray = (List<LinkedHashMap<String, String>>) t;
LinkedHashMap<String, String> headers = reportArray.get(0);
for (String col : headers.keySet()) {
schemaBuilder.addColumn(col);
}
schema = schemaBuilder.build().withLineSeparator("\r");
CsvMapper mapper = new CsvMapper();
mapper.writer(schema).writeValues(entityStream).writeAll(reportArray);
}
}
最佳答案
默认情况下,JAX-RS 仅支持少数 Content-Type
(也取决于实现),例如 XML 和 JSON。
JAX-RS 的思想是将对象转换为特定类型(例如 XML 或 JSON)。这样您就可以为 XML 和 JSON 重复使用相同的对象,而无需知道 Controller 中的输出。然后,如果您想要 CSV 等不同的东西,则需要定义自己的 BodyWriter
,请参见此处的示例:http://www.javaprocess.com/2015/08/a-simple-csv-messagebodywriter-for-jax.html
这里的问题是您的 Controller 是特定于 CSV 的并且不是很灵活。您可以将 csvService
的输出放入一个对象中,然后让 BodyWriter
将其转换为 CSV。
关于java - 导出 CSV 文件 - JAX RS - REST - AJAX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46224071/