java - Spring @ExceptionHandler 返回 HTTP 406

标签 java spring rest spring-mvc exception-handling

我遇到了一些奇怪的错误。

我想做的: 客户要求 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/

相关文章:

c# - 服务定位器反模式适用于工厂注册

java - 如何显示基于外键的列表 groovy grails

Java 等于方法不起作用

java - 如何解决此错误 VFY : unable to resolve virtual method

java - Spring 安全 : method to check if a user has a Hierarchical Role

java - 使用 java 的 Apache NiFi REST Api

java - S4 启动 PE 时数组索引越界

java - ContextLoaderListener 和 ContextLoaderServlet 的区别

java - Spring 属性文件

java - 使用简单的 spring-data-rest 项目获取 404 错误