Spring允许在@ExceptionHandlers内部定义@RestControllerAdvice。
我已经为HTTP400,404,405,.但是,ExceptionHandler for HTTP406 (NOT_ACCEPTABLE)似乎不起作用。处理程序被触发,我在日志中检查了这一点,但是没有使用结果。
我的目标是返回带有JSON主体的HTTP 406。
变体1
@ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public ErrorDTO requestMethodNotSupported(final HttpMediaTypeNotAcceptableException e) {
final ErrorDTO dto = new ErrorDTO(HttpStatus.NOT_ACCEPTABLE, "http.media_not_acceptable");
return dto;
}变体2
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public ResponseEntity<ErrorDTO> requestMethodNotSupported2(final HttpMediaTypeNotAcceptableException e) {
final ErrorDTO dto = new ErrorDTO(HttpStatus.NOT_ACCEPTABLE, "http.media_not_acceptable");
return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).contentType(MediaType.APPLICATION_JSON_UTF8).body(dto);
}但是,我总是从Tomcat获得类似于此的HTML响应:
HTTP Status 406 - 类型:现状报告 电文: 描述:此请求所标识的资源只能生成根据请求“接受”标头不可接受的特性的响应。
而不是
{ "errorCode":406,"errorMessage":"http.media_not_acceptable“}
Request-Headers:
Actual-Response-Headers:
Expected-Response-Headers:
我知道,我可以简单地“修复”客户端发送的,但是如果服务器不知道如何响应,则应该始终使用JSON进行响应。
我使用Spring4.3.3. Jackson和Jackson 2.8.4。
发布于 2016-12-13 14:23:40
最后,我找到了一个解决方案:
与其返回可序列化的对象,不如直接返回字节。
private final ObjectMapper objectMapper = new ObjectMapper();
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public ResponseEntity<byte[]> mediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException e) {
Object response = ...;
try {
return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(objectMapper.writeValueAsBytes(response));
} catch (Exception subException) {
// Should never happen!!!
subException.addSuppressed(e);
throw subException;
}
}编辑:
作为另一种选择,您可以为您的HttpMessageConverter<ErrorResponse>对象创建一个自定义ErrorResponse。
WebMvcConfigurerAdapter#extendMessageConverters(converters)的推动力HttpMessageConverter。getSupportedMediaTypes()返回MediaType.ALLcanRead()返回falsecanWrite()只对ErrorResponse返回truewrite()设置强制CT并将您期望的内容类型转发到包装转换器。- If added as last element then it will only return the result as your expected result, if there was no other matching converter (fallback)
- Requested: json , Returned: json
- Requested: xml , Returned: xml
- Requested: image , Returned: forced CT发布于 2021-01-22 17:10:02
基于@ST-滴滴涕的研究结果。如果您也在扩展ResponseEntityExceptionHandler,那么您就不能仅仅添加另一个方法来处理HttpMediaTypeNotAcceptableException。然而,对整个问题有一个更简单的解决办法:
@Override
public ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
ResponseEntity<Object> response = super.handleHttpMediaTypeNotAcceptable(ex, headers, status, request);
// Workaround to return JSON response for 406
return ResponseEntity.status(NOT_ACCEPTABLE)
.contentType(APPLICATION_JSON)
.body(response.getBody());
}https://stackoverflow.com/questions/40421119
复制相似问题