如何通过使用异常处理程序注释将错误内容写入响应 body 来处理 HttpMediaTypeNotAcceptableException?
How to handle HttpMediaTypeNotAcceptableException by writing error content to the response body using exception handler annotation?
当客户端请求资源产生 application/json 内容时,Accept Header of application/xml。请求因 HttpMediaTypeNotAcceptableException 异常而失败,并通过使用以下代码中提到的异常处理程序注释包装到响应实体 object 中的错误消息 body 中。但是,当使用 HttpMessageConverter 将 return 值写入响应时,我们再次收到 HttpMediaTypeNotAcceptableException。这是因为它使用可接受的请求类型检查响应的可生成内容类型,但这正是我们试图使用错误消息与客户端通信的内容。我该如何解决这个问题?顺便说一句,所有其他异常都可以很好地解析错误消息。请指教
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body,
HttpHeaders headers, HttpStatus status, WebRequest request) {
// Setting the response content type to json
headers.setContentType(MediaType.APPLICATION_JSON);
return ResponseEntity.status(status).headers(headers).body(body);
}
}
我想到了几个选项。一个是你的控制器方法产生 all 内容类型,然后如果内容类型不是你期望的类型,你在你的方法中抛出一个异常,然后异常处理程序可以接受这个异常并且改造它。这是唯一与异常处理程序一起使用的方法,因为异常处理程序仅处理控制器方法中产生的异常。
其他选项是:
- 使用拦截器(但我不确定这是否有效,因为 Spring 可能首先尝试解析控制器方法而不是调用拦截器)。
- 扩展
RequestMappingHandlerMapping
以在找不到合适的方法时调用异常处理程序。您可能需要覆盖方法 handleNoMatch
。在那里你需要获得对 HandlerExceptionResolver
列表的引用
第一个最容易理解,最新的可能是最多的'extensible',但也需要对Spring的内部结构有所了解。
通过为 ExceptionHandlerExceptionResolver
设置不同的内容协商策略 FixedContentNegotiationStrategy
和为 RequestResponseBodyMethodProcessor
设置不同的内容协商策略 HeaderContentNegotiationStrategy
来解决。
当客户端请求资源产生 application/json 内容时,Accept Header of application/xml。请求因 HttpMediaTypeNotAcceptableException 异常而失败,并通过使用以下代码中提到的异常处理程序注释包装到响应实体 object 中的错误消息 body 中。但是,当使用 HttpMessageConverter 将 return 值写入响应时,我们再次收到 HttpMediaTypeNotAcceptableException。这是因为它使用可接受的请求类型检查响应的可生成内容类型,但这正是我们试图使用错误消息与客户端通信的内容。我该如何解决这个问题?顺便说一句,所有其他异常都可以很好地解析错误消息。请指教
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body,
HttpHeaders headers, HttpStatus status, WebRequest request) {
// Setting the response content type to json
headers.setContentType(MediaType.APPLICATION_JSON);
return ResponseEntity.status(status).headers(headers).body(body);
}
}
我想到了几个选项。一个是你的控制器方法产生 all 内容类型,然后如果内容类型不是你期望的类型,你在你的方法中抛出一个异常,然后异常处理程序可以接受这个异常并且改造它。这是唯一与异常处理程序一起使用的方法,因为异常处理程序仅处理控制器方法中产生的异常。
其他选项是:
- 使用拦截器(但我不确定这是否有效,因为 Spring 可能首先尝试解析控制器方法而不是调用拦截器)。
- 扩展
RequestMappingHandlerMapping
以在找不到合适的方法时调用异常处理程序。您可能需要覆盖方法handleNoMatch
。在那里你需要获得对HandlerExceptionResolver
列表的引用
第一个最容易理解,最新的可能是最多的'extensible',但也需要对Spring的内部结构有所了解。
通过为 ExceptionHandlerExceptionResolver
设置不同的内容协商策略 FixedContentNegotiationStrategy
和为 RequestResponseBodyMethodProcessor
设置不同的内容协商策略 HeaderContentNegotiationStrategy
来解决。