【发布时间】:2021-03-09 18:59:01
【问题描述】:
我有一个 Spring Boot 应用程序,它的端点已经在工作,可以生成一个 xlsx 文件。
现在,我想在这个端点上实现内容协商,但我总是收到406 Not Acceptable。
{
"timestamp": "2021-03-09T18:44:56.997+0000",
"status": 406,
"error": "Not Acceptable",
"message": "Could not find acceptable representation",
"path": "/students/excel"
}
我正在使用 URL 参数,我这样称呼它
localhost:8080/students/excel/excel?format=xlsx
实现
端点
@PostMapping(path = "/excel", produces = {"application/vnd.ms-excel"})
public byte[] generateExcel(HttpServletResponse response, final @RequestBody @NonNull Criteria criteria) {
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=Students.xlsx");
return studentService.generateExcelReport(response, criteria);
}
完成 excel 文件的方法。
public static byte[] write(HttpServletResponse response, final @NonNull XSSFWorkbook workbook) {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
os.writeTo(response.getOutputStream());
workbook.write(os);
workbook.close();
return os.toByteArray();
} catch (final IOException ex) {
throw new RuntimeException("Error generating excel", ex);
}
}
以及实现WebMvcConfigurer的WebConfiguration上的相关方法
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("format").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xlsx", MediaType.MULTIPART_FORM_DATA);
}
我尝试了很多与MediaType 和WebConfiguration 的组合以及produces 的属性,比如
application/csv 检查是否有可能由于 excel 文件和其他文件的格式化而起作用。但我无法克服这种状态。将其设置为 application/json 和 text/plain 时,它可以工作,但它不是想要的功能或正确的功能。
当我不使用内容协商时,excel 的生成就像我提到的那样工作。
编辑:
根据建议,我将内容类型更改为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,并在Postman 上更改了Accept 和Content-Type 的标头,仍然收到406。
我也调试了应用程序,它没有进入端点的方法,它似乎因为产生的值而立即失败。
我想补充一点,这是一个接受 JSON 的 POST 请求。因此,在 Postman 上使用任何其他内容类型都会破坏它。
更新
它通过使用接受头而不是参数并更改WebConfigurer 方法来工作。但是,我想使用 URL 参数并了解它们为什么不起作用。
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
favorParameter(false).
ignoreAcceptHeader(false).
useJaf(false);
}
【问题讨论】:
-
您似乎忘记在通话中将
Accept标头设置为application/vnd.ms-excel。 -
xslx 的内容类型是
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet -
我尝试实施您的两个建议。 @Jens 我忘了提到这是我使用的第一个 Content-Type 并且现在阅读它是首选的
application/vnd.ms-excel也许我错了,我在 @Seelenvirtuose 的建议下再次尝试了,遗憾的是我仍然收到406. 我将通过测试更新问题。我也很担心MediaType.MULTIPART_FORM_DATA,我完全不确定。 -
您是否更改了produces和set cntenttype中的字符串?
-
@Jens 是的,我都有。
标签: java excel spring-boot content-negotiation media-type