I need to return a Microsoft Excel file from a Java REST service. I'm using WebSphere 8.5 which inherently uses Apache Wink as it's JAX-RS implementation; that's a requirement which I can not change. I am also using Java 7 JDK. Here is the error I'm receiving:
org.apache.wink.server.internal.handlers.FlushResultHandler handleResponse The system could not find a javax.ws.rs.ext.MessageBodyWriter or a DataSourceProvider class for the com.somewhere.else.message.core.BaseResponseMessage type and application/vnd.ms-excel mediaType. Ensure that a javax.ws.rs.ext.MessageBodyWriter exists in the JAX-RS application for the type and media type specified.
Here is my Java Resource class method:
@GET
@Path("/report")
@Produces("application/vnd.ms-excel")
public Response getReport() {
int fileSize = 0;
byte[] reportByteArray = null;
ResponseBuilder responseBuilder = null;
InputStream report = null;
BaseResponseMessage<InputStream> baseResponseMessage = new
BaseResponseMessage<InputStream>();
Path reportPath = null;
String localPath = "C:/Users/me/Report.xls";
responseBuilder = Response.ok(baseResponseMessage);
responseBuilder.header("Content-Description", "File Transfer");
responseBuilder.header("Content-Disposition", "attachment;
filename=Report.xls");
responseBuilder.header("Content-Transfer-Encoding", "binary");
responseBuilder.header("Connection", "Keep-Alive");
reportPath = Paths.get(localPath);
if (Files.exists(reportPath)) {
if (Files.isReadable(reportPath)) {
reportByteArray = Files.readAllBytes(reportPath);
report = new ByteArrayInputStream(reportByteArray);
}
}
fileSize = report.available();
responseBuilder.header("Content-Length", fileSize);
baseResponseMessage.setPayload(report);
return responseBuilder.build();
}
I do know from looking at the debugger that the path and the excel file are found correctly, and the fileSize is populated correctly as well.
I will gladly provide any more information that is needed. Thank you for your time!
I think the problem is on the @Produces
annotation. JAX-RS may not know how to handle "application/vnd.ms-excel"
by default. You can try using
@Produces( MediaType.APPLICATION_OCTET_STREAM)
Here is the sample code,
Create a JEE 6 web project
Created an Application Class
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/services/*")
public class MyApplication extends Application {
}
Created a REST Resource class,
import java.io.File;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
@Path("/hello")
public class HelloResource {
@GET
@Path("excel")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response test2() {
File file = new File("C:/users/arun/rest-test.xlsx");
ResponseBuilder rb = Response.ok(file);
rb.header("content-disposition", "attachment; filename=rest-test.xlsx");
return rb.build();
}
}