使用ApacheWink通过JavaREST服务返回excel文档

使用ApacheWink通过JavaREST服务返回excel文档,java,excel,rest,websphere-8,apache-wink,Java,Excel,Rest,Websphere 8,Apache Wink,我需要从Java REST服务返回Microsoft Excel文件。我正在使用WebSphere8.5,它固有地使用ApacheWink作为JAX-RS实现;这是我不能改变的要求。我也在使用Java7JDK。以下是我收到的错误: org.apache.wink.server.internal.handlers.FlushResultHandler HandlerResponse系统找不到 javax.ws.rs.ext.MessageBodyWriter或的DataSourceProvider

我需要从Java REST服务返回Microsoft Excel文件。我正在使用WebSphere8.5,它固有地使用ApacheWink作为JAX-RS实现;这是我不能改变的要求。我也在使用Java7JDK。以下是我收到的错误:

org.apache.wink.server.internal.handlers.FlushResultHandler HandlerResponse系统找不到 javax.ws.rs.ext.MessageBodyWriter或的DataSourceProvider类 com.somewhere.else.message.core.BaseResponseMessage类型和 application/vnd.ms-excel mediaType。确保 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();
}
@GET
@路径(“/report”)
@生成(“应用程序/vnd.ms excel”)
公共响应getReport(){
int fileSize=0;
字节[]reportByteArray=null;
ResponseBuilder ResponseBuilder=null;
InputStream报告=null;
BaseResponseMessage BaseResponseMessage=新建
BaseResponseMessage();
路径reportPath=null;
字符串localPath=“C:/Users/me/Report.xls”;
responseBuilder=Response.ok(baseResponseMessage);
header(“内容描述”、“文件传输”);
标题(“内容处置”、“附件”;
文件名=Report.xls”);
header(“内容传输编码”、“二进制”);
标题(“连接”,“保持活动”);
reportPath=path.get(localPath);
if(Files.exists(reportPath)){
if(Files.isReadable(reportPath)){
reportByteArray=Files.readAllBytes(reportPath);
报告=新的ByteArrayInputStream(reportByteArray);
}
}
fileSize=report.available();
header(“内容长度”,文件大小);
baseResponseMessage.setPayload(报告);
返回responseBuilder.build();
}
通过查看调试器,我确实知道路径和excel文件已正确找到,并且文件大小也已正确填充


我很乐意提供所需的更多信息。谢谢你抽出时间

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

@Produces( MediaType.APPLICATION_OCTET_STREAM)
这是示例代码

  • 创建一个JEE6Web项目

  • 创建了一个应用程序类

    import javax.ws.rs.ApplicationPath;  
    import javax.ws.rs.core.Application; 
    
    @ApplicationPath("/services/*")  
    public class MyApplication extends Application {  
    
    }  
    
  • 创建了一个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("/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();  
        }  
    }  
    

  • 问题在于BaseResponseMessage的存在。显然,因为我实际上是在对象中返回BaseResponseMessage,而不是实际的JAX-RS,所以我不知道如何处理它,因为(正如错误所述)没有一个MessageBodyWriter或DataSourceProvider专门与该组合相关联。有趣的是,如果我仔细阅读,错误消息实际上揭示了实际问题!:p

    修改上述代码以删除BaseResponseMessage并执行以下操作时:

    responseBuilder=Response.ok(报告)

    那么它就可以正常工作了


    [顺便说一句,返回一个对象并不是一个好主意;代码已经修改为返回一个对象。]

    显然这不是问题所在,因为我在进行更改时收到了这样的消息:
    org.apache.wink.server.internal.handlers.FlushResultHandler HandlerResponse系统找不到com.where.else.message.core.BaseResponseMessage类型和应用程序/八位字节流的javax.ws.rs.ext.MessageBodyWriter或DataSourceProvider类媒体类型。确保JAX-rs应用程序中存在指定类型和媒体类型的javax.ws.rs.ext.MessageBodyWriter。
    这可能与BaseResponseMessage中返回的响应有关,而不是直接返回?