问题描述
我有一个 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);
}
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);
}
}
以及实现 WebConfiguration
的 WebMvcConfigurer
上的相关方法
@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
时,它可以工作,但不是想要的功能或正确的功能。
编辑:
根据建议,我将内容类型更改为 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);
}
解决方法
我找到了一个解决方案,使其能够使用 URL 参数,因为这是我的第一个意图。
我在 vnd.ms-excel
上添加了一个新的媒体类型 WebConfiguration
,如下所示。
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("format").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xlsx",new MediaType("application","vnd.ms-excel"));
}
在请求的 Accept
标头上,我添加了值 application/vnd.ms-excel
。
最后,通过现在使用所需格式调用 excel 端点,它可以正确生成 excel 文件。
localhost:8080/students/excel/excel?format=xlsx