Spring允许在@Rest控件建议
中定义@ExceptionHandler
。
我已经在那里为HTTP 400、404、405等定义了许多其他异常处理程序,。。。然而,HTTP 406的ExceptionHandler(不可接受)似乎不起作用。处理程序被触发,我在日志中对此进行了检查,但没有使用结果。
我的目标是返回一个带有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得到类似的超文本标记语言响应:
HTTP状态406-
类型:状态报告
消息:
描述:此请求标识的资源只能根据请求“accept”标头生成具有不可接受特征的响应。
而不是
{"errorCode": 406,"errorMessage":"http.media_not_acceptable"}
请求标头:
实际响应标题:
预期的响应标头:
我知道我可以简单地“修复”客户机发送的Accept头,但是如果服务器不知道如何响应,则应该始终使用JSON进行响应。
我使用Spring 4.3.3。RELEASE和Jackson 2.8.4。
基于@ST-DDT调查结果。如果您也在扩展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());
}
最后,我找到了一个解决方案:
与其返回可序列化对象,不如直接返回字节。
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
WebMvcConfigrerAdapter#extendMessageConverters(转换器)
HttpMessageConverter
。getSupport dMediaTypes()
返回MediaType。ALL
canRead()
返回falsecanWrit()
仅对您的错误响应
write()
设置强制CT并将您期望的内容类型转发到包装的转换器。我正在编写一个使用Java和Apache HttpClient的播客下载器。它适用于大多数RSS提要,但这一个失败了,出现了“406不可以接受”的错误。 链接是http://sqrpt.com/feed/podcast/
我们的项目中有Spring-boot/hibernate/PostgreSQL应用程序,并使用Hikari作为连接池。我们不断遇到以下问题:几个小时后,活动连接数增长到极限,我们得到如下错误(完整堆栈跟踪位于问题的末尾): 以下是版本信息: JPA/Hibernate配置: HikariCP配置: 完整堆栈跟踪:
问题内容: 我正在尝试生成一个简单的JSON响应。现在,我收到406 Not Acceptable错误。Tomcat说:“此请求标识的资源只能根据请求“接受”标头生成特性不可接受的响应。” 即使我的标题是 在tomcat / lib中,我拥有所有的Tomcat jar,Spring jar和jackson-all-1.9.0.jar。我在Tomcat 7中使用Spring 3.2.2。 我知道这个
我正在尝试生成一个简单的JSON响应工作。现在我收到406不接受错误。Tomcat说“此请求标识的资源仅能够根据请求“接受”标头生成具有不可接受特征的响应。”即使我的标头是 在tomcat/lib中,我有所有的tomcat罐子、Spring罐子和jackson-all-1.9.0。罐子我将Spring 3.2.2用于Tomcat 7。 我知道这个问题已经讨论过很多次了,但是没有一个解决方案对我有用
应用程序是使用Spring MVC 4、Hibernate和jQuery开发的 下面jquery AJAX调用没有给出正确的响应。。说明406错误(不可接受) 我知道这是一个非常古老而常见的问题。我尝试过: 杰克逊罐子 在请求映射注释中:生产者作为JSON 在请求映射注释中:标头为JSON 2和3的组合 $. post而不是$. ajax(我知道这没什么区别) 我的bean对象(Validatio