ST-*_*DDT 2 java rest spring exception-handling http
Spring允许在@ExceptionHandlers内部定义@RestControllerAdvice。
我已经ExceptionHandlers在那里为HTTP 400、404、405 等定义了许多其他协议。但是,HTTP 406的ExceptionHandler(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;
}
Run Code Online (Sandbox Code Playgroud)
变体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);
}
Run Code Online (Sandbox Code Playgroud)
但是我总是从Tomcat收到类似于以下内容的HTML响应:
HTTP状态406-
类型:状态报告
信息:
描述:此请求标识的资源只能根据请求“接受”标头生成特性不可接受的响应。
代替
{“ errorCode”:406,“ errorMessage”:“ http.media_not_acceptable”}
请求标头:
实际响应标题:
预期响应标题:
我知道我可以简单地“修复”客户端发送的Accept-Header,但是如果服务器不知道如何响应,则服务器应始终以JSON响应。
我使用Spring 4.3.3.RELEASE和Jackson 2.8.4。
最后,我找到了一个解决方案:
无需返回可序列化的对象,而是直接返回字节。
private final ObjectMapper objectMapper = new ObjectMapper();
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public ResponseEntity<byte[]> requestMethodNotSupported(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;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
或者,您可以HttpMessageConverter<ErrorResponse>为ErrorResponse对象创建自定义。
WebMvcConfigurerAdapter#extendMessageConverters(converters)HttpMessageConverter能够创建预期结果/内容类型的。getSupportedMediaTypes() 退货 MediaType.ALLcanRead() 返回假 canWrite()只为您返回true ErrorResponsewrite() 设置强制CT并将您期望的内容类型转发给包装的转换器。| 归档时间: |
|
| 查看次数: |
1218 次 |
| 最近记录: |