使用JERSEY输入和输出二进制流?

问题

我正在使用Jersey实现一个主要检索和提供JSON编码数据的RESTful API。但我有一些情况需要完成以下事项:

  • 导出可下载的文档,例如PDF,XLS,ZIP或其他二进制文件。
  • 检索多部分数据,例如一些JSON加上传的XLS文件

我有一个基于JQuery的单页Web客户端,它可以为这个Web服务创建AJAX调用。目前,它不进行表单提交,并使用GET和POST(使用JSON对象)。我应该使用表单发送数据和附加的二进制文件,还是可以使用JSON plus二进制文件创建多部分请求?

我的应用程序的服务层当前在生成PDF文件时创建ByteArrayOutputStream。通过Jersey将此流输出到客户端的最佳方法是什么?我已经创建了一个MessageBodyWriter,但我不知道如何从Jersey资源中使用它。这是正确的方法吗?

我一直在查看泽西岛附带的样本,但还没有找到任何说明如何做这些事情的东西。如果重要的是,我正在使用泽西与杰克逊做没有XML步骤的对象 - > JSON,并没有真正使用JAX-RS。


#1 热门回答(107 赞)

我通过扩展StreamingOutput对象设法获得了ZIP文件或PDF文件。以下是一些示例代码:

@Path("PDF-file.pdf/")
@GET
@Produces({"application/pdf"})
public StreamingOutput getPDF() throws Exception {
    return new StreamingOutput() {
        public void write(OutputStream output) throws IOException, WebApplicationException {
            try {
                PDFGenerator generator = new PDFGenerator(getEntity());
                generator.generatePDF(output);
            } catch (Exception e) {
                throw new WebApplicationException(e);
            }
        }
    };
}

PDFGenerator类(我自己的用于创建PDF的类)从write方法获取输出流并写入而不是新创建的输出流。

不知道这是否是最佳方式,但它确实有效。


#2 热门回答(27 赞)

我不得不返回一个rtf文件,这对我有用。

// create a byte array of the file in correct format
byte[] docStream = createDoc(fragments); 

return Response
            .ok(docStream, MediaType.APPLICATION_OCTET_STREAM)
            .header("content-disposition","attachment; filename = doc.rtf")
            .build();

#3 热门回答(22 赞)

我正在使用此代码将泽西的excel(xlsx)文件(Apache Poi)导出为附件。

@GET
@Path("/{id}/contributions/excel")
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public Response exportExcel(@PathParam("id") Long id)  throws Exception  {

    Resource resource = new ClassPathResource("/xls/template.xlsx");

    final InputStream inp = resource.getInputStream();
    final Workbook wb = WorkbookFactory.create(inp);
    Sheet sheet = wb.getSheetAt(0);

    Row row = CellUtil.getRow(7, sheet);
    Cell cell = CellUtil.getCell(row, 0);
    cell.setCellValue("TITRE TEST");

    [...]

    StreamingOutput stream = new StreamingOutput() {
        public void write(OutputStream output) throws IOException, WebApplicationException {
            try {
                wb.write(output);
            } catch (Exception e) {
                throw new WebApplicationException(e);
            }
        }
    };


    return Response.ok(stream).header("content-disposition","attachment; filename = export.xlsx").build();

}