Spring return JSON for HTTP 406 (NOT_ACCEPTABLE)

故事扮演 提交于 2019-12-06 13:32:23

Finally I found a solution for this:

Instead of returning a serializable object just return the bytes directly.

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;
    }
}

EDIT:

As an alternative you can create a custom HttpMessageConverter<ErrorResponse> for your ErrorResponse object.

  • Go to your or create a impl of WebMvcConfigurerAdapter#extendMessageConverters(converters)
  • Pick a HttpMessageConverter that is capable of creating your expected result/content type.
  • Wrap it in a way to fulfill the following conditions:
    • getSupportedMediaTypes() returns MediaType.ALL
    • canRead() returns false
    • canWrite()returns only true for your ErrorResponse
    • write() sets the forced CT and forward your expected content type to the wrapped converter.
  • Add your wrapper to the converters list.
    • If added as first element then it will always return your expected result (forced)
      • Requested: json , Returned: forced CT
      • Requested: xml , Returned: forced CT
      • Requested: image , Returned: forced 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!