使用Apache Wink通过Java REST服务返回Excel文档

我需要从Java REST服务返回一个Microsoft Excel文件。 我正在使用WebSphere 8.5,它固有地使用Apache Wink,因为它是JAX-RS实现; 这是我不能改变的一个要求。 我也在使用Java 7 JDK。 这是我收到的错误:

org.apache.wink.server.internal.handlers.FlushResultHandler handleResponse系统找不到com.somewhere.else.message.core.BaseResponseMessagetypes的javax.ws.rs.ext.MessageBodyWriter或DataSourceProvider类和application / vnd.ms-excel mediaType。 确保JAX-RS应用程序中存在指定的types和媒体types的javax.ws.rs.ext.MessageBodyWriter。

这是我的Java资源类的方法:

@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(); } 

我知道通过查看debugging器的path和excel文件find正确,并且fileSize正确填充以及。

我会很乐意提供更多所需的信息。 感谢您的时间!

我认为问题出在@Produces注释上。 JAX-RS默认情况下可能不知道如何处理“application / vnd.ms-excel”。 你可以尝试使用

 @Produces( MediaType.APPLICATION_OCTET_STREAM) 

这里是示例代码,

  1. 创build一个JEE 6 Web项目
  2. 创build一个应用程序类

    import javax.ws.rs.ApplicationPath;
    import javax.ws.rs.core.Application;

    @ApplicationPath( “/服务/ *”)
    公共类MyApplication扩展应用程序{

    }

  3. 创build了一个REST资源类,

    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( “/你好”)
    公共类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(); } 

    }

问题是BaseResponseMessage的存在。 显然是因为我实际上是在Response对象中返回BaseResponseMessage,而不是实际的InputStream,所以 JAX-RS不知道如何处理它(因为错误状态),没有一个MessageBodyWriter或者DataSourceProvider与这个组合特别关联。 有趣的是,如果错误信息真正揭示了实际的问题,我已经仔细阅读了! :p

当上面的代码被修改为删除BaseResponseMessage并做这样的事情:

responseBuilder = Response.ok(report);

那么它将工作得很好。

[ 顺便说一句,返回InputStream不是一个好主意, 该代码已被修改为返回一个StreamingOutput对象。]

Interesting Posts