Reputation: 133
I create a function to download a CSV File. I will use that to download simple reports. I got the error below on Netbeans using Wildfly and JAX RS
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
Here is my Code:
Controller
Update on 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();
}
}
The csvService
returns a String like:
Column1,column2,column3
cellInfo1,cellInfo2,cellInfo3
,cellInfo2,cellInfo3
cellInfo1,,cellInfo3
cellInfo1,cellInfo2,
,,cellInfo3
I tried using a different @Produces
=> @Produces('text/csv')
, @Produces('application/octet-stream')
If I remove the Annotation @Produces
I got the following error:
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) {
}
});
What I'm doing wrong ? Could you help to me please!
.
SOLUTION Thanks to @albert-bos
1st. Check the link in the solution from @albert-bos below.
2nd: Check this link too
3rd:
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:
I create a class called CSVMessageBodyWritter (check the link) but I adpated the method 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);
}
}
Upvotes: 4
Views: 12075
Reputation: 456
window.open("http://localhost:8080/xmlcompare-rs/xmlcompare/excelmisreport");
@GET
@Path("excelmisreport")
@Produces("application/vnd.ms-excel")
public Response getExcelReport() {
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition",
"attachment; filename=MISReport.xls");
return response.build();
}
Upvotes: 2
Reputation: 1
I don't have enough rep so can't add a comment for the answer of Albert Bos.
There is a PITFALL with that solution: you can suddenly run into the problem when you get empty csv file even if it should have a data. It happens because of result of getSize method.
I'm not sure which version of JAX-RS is supposed to be used in that example (in the article), but accordingly to the jax-rs documentation, result of getSize is ignored for JAX-RS 2.0, but for JAX-RS 1.X it seems to be used and "return 0" makes downloaded file empty. Make sure you return "-1". I've encountered it when tried to implement csv export in JIRA rest plugin (I guess it's based on first version of JAX-RS).
Upvotes: 0
Reputation: 2062
JAX-RS only supports a few Content-Type
s by default (also depending on implementation), like XML and JSON.
The idea of JAX-RS is that it will convert an object to a certain type (e.g. XML or JSON). This is so you can re-use the same object for XML and JSON, without knowing the output in your Controller. Then If you want something different like CSV, you need to define your own BodyWriter
, see example here: http://www.javaprocess.com/2015/08/a-simple-csv-messagebodywriter-for-jax.html
The problem here is that your controller is to specific for CSV and isn't very flexible. You could put your output of csvService
into an object and let the BodyWriter
convert it into CSV.
Upvotes: 3