【问题标题】:MessageBodyWriter not found for media type=application/octet-stream, type=class org.apache.poi.xssf.usermodel.XSSFWorkbook找不到媒体类型 = 应用程序/八位字节流,类型 = 类 org.apache.poi.xssf.usermodel.XSSFWorkbook 的 MessageBodyWriter
【发布时间】:2018-05-17 21:24:10
【问题描述】:

我有下面的类,它试图以 excel 电子表格的形式返回一些数据。我收到了错误

找不到媒体类型=application/octet-stream, type=class org.apache.poi.xssf.usermodel.XSSFWorkbook 的MessageBodyWriter

我也尝试过@Produces("application/vnd.ms-excel"),但也遇到了类似的错误。有人对我如何让这个返回电子表格有建议吗?上次我收到与此类似的错误消息(抱怨找不到数组列表的消息正文编写器)时,我只是将它包装在一个通用实体中。这一次没有奏效。

@PermitAll
@Path("uploadWorkbook")
public class ExcelUploadResource {

    @Context
    ResourceContext resourceContext;

    @Inject
    JobService jobService;

    @GET
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response list() {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Job definitions");

        int rowNum = 0;
        for(Job job : jobService.list()){
            Row row = sheet.createRow(rowNum++);
            int cellNum = 0;
            for(String field : job.toList()){
                Cell cell = row.createCell(cellNum++);
                cell.setCellValue(field);
            }
        }

        GenericEntity<XSSFWorkbook> entity = new GenericEntity<XSSFWorkbook>(workbook) {};

        ResponseBuilder response = Response.ok(entity);
        response.header("Content-Disposition",
            "attachment; filename=jobs.xls");
        return response.build();
    }   
}

【问题讨论】:

    标签: jersey apache-poi


    【解决方案1】:

    您不能只使用数据类型为application/octet-stream 的任意对象。您首先需要了解的是对象是如何序列化的。这是通过使用MessageBodyWriters 完成的。您可以通过JAX-RS Entity Providers了解更多信息。

    编写器的工作方式是传递实体和响应流。编写器应该获取实体并将实体的内容写入响应流。根据我们返回的实体类型和预期的媒体类型查找作者,在您的情况下,您希望它是 application/octet-stream

    错误的意思是没有编写器来处理您的XSSFWorkbook 的转换。当您谈论application/octet-stream 时,您主要是在处理二进制文件。 XSSFWorkbook 不是二进制文件。在使用application/octet-stream 时,您将主要使用byte[]FileInputStreamStreamingOutput 实体类型。因此,如果您想使用application/octet-stream,则需要将实体更改为其中一种类型。

    我从未使用过 Apache POI,但只是通过一个快速教程,看起来您可能想要在这种情况下使用 StreamingOutput,您可以使用 XSSFWorkbook#write(OutputStream) 方法编写工作簿到StreamingOutput

    public Response getExcelFile() {
        XSSFWorkbook workbook = new XSSFWorkbook();
        ...
        StreamingOutput output = new StreamingOutput() {
            @Override
            public void write(OutputStream out)
                    throws IOException, WebApplicationException {
    
                workbook.write(out);
                out.flush();
            }
        };
        return Response.ok(output)
                .header(HttpHeaders.CONTENT_DISPOSITION,
                        "attachment; filename=jobs.xls")
                .build();
    }
    

    【讨论】:

    • 太棒了。它有效,并且对原因有很好的解释
    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 2015-03-27
    • 2017-07-24
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 2015-05-22
    相关资源
    最近更新 更多