我遇到了一些奇怪的错误。
我想做的: 客户要求 GET:/invoices/invoiceNumber 标题为 Accept: application/pdf ,我想返回 PDF 文件。如果客户端忘记了 header ,我将返回 HTTP 406。
返回 PDF 字节的方法抛出由 Spring ExceptionHandler 处理的 DocumentNotFoundException 并且应该返回 404,但它没有。取而代之的是,我得到了 406 和服务器日志:
2017-06-01 15:14:03.844 WARN 2272 --- [qtp245298614-13] o.e.jetty.server.handler.ErrorHandler : Error page loop /error
当 Spring Security 返回 HTTP 401 时,同样的魔法会发生。
所以我认为问题是客户端接受 application/pdf
但 Spring ExceptionHandler 返回 application/json
,所以 jetty 调度程序用 406 覆盖 404 :(
我的代码:
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Invoice not found")
@ExceptionHandler(DocumentNotFoundException.class)
public void handleException() {
//impl not needed
}
@GetMapping(value = "invoices/**", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getInvoicePdf(HttpServletRequest request) {
String invoiceNumber = extractInvoiceNumber(request);
final byte[] invoicePdf = invoiceService.getInvoicePdf(invoiceNumber);
return new ResponseEntity<>(invoicePdf, buildPdfFileHeader(invoiceNumber), HttpStatus.OK);
}
@GetMapping(value = "invoices/**")
public ResponseEntity getInvoiceOther() {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
}
有人可以帮助我理解吗?
最佳答案
问题是 Spring 尝试将错误响应转换为 application/pdf
但未能找到合适的支持转换为 PDF 的 HttpMessageConverter
。
最简单的解决方案是手动创建错误响应:
@ExceptionHandler(DocumentNotFoundException.class)
public ResponseEntity<?> handleException(DocumentNotFoundException e) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body("{\"error\": \"Invoice not found\"}");
}
这会绕过消息转换并生成 HTTP 404 响应代码。
关于java - Spring @ExceptionHandler 返回 HTTP 406,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44309055/