4

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!

2 Answers 2

6

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,

  1. Create a JEE 6 web project

  2. Created an Application Class

    import javax.ws.rs.ApplicationPath;  
    import javax.ws.rs.core.Application; 
    
    @ApplicationPath("/services/*")  
    public class MyApplication extends Application {  
    
    }  
    
  3. 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();  
        }  
    }  
    
Sign up to request clarification or add additional context in comments.

1 Comment

Apparently that was not the issue as I receive this when making that change: 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/octet-stream mediaType. Ensure that a javax.ws.rs.ext.MessageBodyWriter exists in the JAX-RS application for the type and media type specified. Perhaps it has something to do with the response being returned in a BaseResponseMessage instead of directly?
0

The problem was the existence of the BaseResponseMessage. Apparently because I was actually returning the BaseResponseMessage in the Response object instead of the actual InputStream JAX-RS didn't know how to process it since (as the error states) there isn't a MessageBodyWriter or DataSourceProvider specifically associated with that combination. Funny how the error message actually revealed the actual problem had I read it more closely! :p

When the code above is modified to remove the BaseResponseMessage and do something like this:

responseBuilder = Response.ok(report);

then it will work just fine.

[As an aside, returning an InputStream is not really a good idea anyway; the code has since been modified to return a StreamingOutput object.]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.