首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring返回JSONforHTTP406 (NOT_ACCEPTABLE)

Spring返回JSONforHTTP406 (NOT_ACCEPTABLE)
EN

Stack Overflow用户
提问于 2016-11-04 11:06:47
回答 2查看 2.5K关注 0票数 5

Spring允许在@ExceptionHandlers内部定义@RestControllerAdvice

我已经为HTTP400,404,405,.但是,ExceptionHandler for HTTP406 (NOT_ACCEPTABLE)似乎不起作用。处理程序被触发,我在日志中检查了这一点,但是没有使用结果。

我的目标是返回带有JSON主体的HTTP 406。

变体1

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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:

  • 内容-类型: text/html

Expected-Response-Headers:

  • 内容-类型:应用程序/json

我知道,我可以简单地“修复”客户端发送的,但是如果服务器不知道如何响应,则应该始终使用JSON进行响应。

我使用Spring4.3.3. Jackson和Jackson 2.8.4。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-13 14:23:40

最后,我找到了一个解决方案:

与其返回可序列化的对象,不如直接返回字节。

代码语言:javascript
复制
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.ALL
    • canRead()返回false
    • canWrite()只对ErrorResponse返回true
    • write()设置强制CT并将您期望的内容类型转发到包装转换器。

  • 将包装器添加到转换器列表中。
    • 如果作为第一个元素添加,它将始终返回您的预期结果(强制)
      • 要求: json,返回:强制CT
      • 请求: xml,返回:强制CT
      • 要求:图像,返回:强制CT

代码语言:javascript
复制
- 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
票数 7
EN

Stack Overflow用户

发布于 2021-01-22 17:10:02

基于@ST-滴滴涕的研究结果。如果您也在扩展ResponseEntityExceptionHandler,那么您就不能仅仅添加另一个方法来处理HttpMediaTypeNotAcceptableException。然而,对整个问题有一个更简单的解决办法:

代码语言:javascript
复制
    @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());
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40421119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档