REST返回XSSFWorkbook报错:找不到对应MessageBodyWriter
解决JAX-RS返回Excel表格的MessageBodyWriter错误
我来帮你搞定这个问题!你遇到的MessageBodyWriter not found错误,核心原因是JAX-RS没有内置的序列化器来直接处理XSSFWorkbook对象,而且GenericEntity是用来解决泛型集合(比如ArrayList<T>)的类型擦除问题的,对单个XSSFWorkbook对象不起作用。咱们换个思路,直接把Workbook写入HTTP响应的输出流即可,具体步骤如下:
关键修改点
- 使用
StreamingOutput来封装Workbook的写入逻辑,让JAX-RS能正确处理流输出 - 修正MIME类型:
XSSFWorkbook对应xlsx格式,要使用application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(旧的application/vnd.ms-excel对应xls格式的HSSFWorkbook) - 文件名改为
jobs.xlsx,和实际格式匹配 - 不需要用
GenericEntity包装单个Workbook对象
修改后的完整代码
@PermitAll @Path("uploadWorkbook") public class ExcelUploadResource { @Context ResourceContext resourceContext; @Inject JobService jobService; @GET @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") 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); } } // 使用StreamingOutput来处理Workbook的写入 StreamingOutput output = outputStream -> { try { workbook.write(outputStream); } finally { workbook.close(); } }; ResponseBuilder response = Response.ok(output); response.header("Content-Disposition", "attachment; filename=jobs.xlsx"); return response.build(); } }
额外说明
- 一定要记得关闭
XSSFWorkbook,避免资源泄漏,这里我们在StreamingOutput的finally块里处理了关闭逻辑 - 如果你的API需要同时支持xls和xlsx格式,可以根据需求切换
HSSFWorkbook/XSSFWorkbook,并对应修改MIME类型和文件名后缀
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

