Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如何通过使用异常处理程序注释将错误内容写入响应正文来处理HttpMediaTypeNotAcceptableException?_Spring_Spring Mvc_Spring Restcontroller_Spring Web - Fatal编程技术网

Spring 如何通过使用异常处理程序注释将错误内容写入响应正文来处理HttpMediaTypeNotAcceptableException?

Spring 如何通过使用异常处理程序注释将错误内容写入响应正文来处理HttpMediaTypeNotAcceptableException?,spring,spring-mvc,spring-restcontroller,spring-web,Spring,Spring Mvc,Spring Restcontroller,Spring Web,当客户端请求资源生成application/json内容时,Accept头为application/xml。请求因HttpMediaTypeNotAcceptableException异常而失败,并通过使用异常处理程序注释将其包装到响应实体对象中的错误消息正文中,如下面代码中所述。但是,当使用HttpMessageConverter将返回值写入响应时,我们再次收到HttpMediaTypeNotAcceptableException。这是因为它会检查可生产内容类型,以获得具有可接受请求类型的响应

当客户端请求资源生成application/json内容时,Accept头为application/xml。请求因HttpMediaTypeNotAcceptableException异常而失败,并通过使用异常处理程序注释将其包装到响应实体对象中的错误消息正文中,如下面代码中所述。但是,当使用HttpMessageConverter将返回值写入响应时,我们再次收到HttpMediaTypeNotAcceptableException。这是因为它会检查可生产内容类型,以获得具有可接受请求类型的响应,但这正是我们正试图使用错误消息与客户机通信的内容。我如何解决这个问题?顺便说一句,所有其他异常都在解析精细到错误消息。请告知

@ControllerAdvice
    public class RestExceptionHandler extends ResponseEntityExceptionHandler {

     @Override
      protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body,
          HttpHeaders headers, HttpStatus status, WebRequest request) {
          // Setting the response content type to json
          headers.setContentType(MediaType.APPLICATION_JSON);
        return ResponseEntity.status(status).headers(headers).body(body);
      }
    }
@ControllerAdvice
公共类RestExceptionHandler扩展了ResponseEntityExceptionHandler{
@凌驾
protected ResponseEntity handleExceptionInternal(对象体除外,
HttpHeaders标头、HttpStatus状态、WebRequest请求){
//将响应内容类型设置为json
headers.setContentType(MediaType.APPLICATION_JSON);
返回ResponseEntity.status(status).headers(headers.body(body);
}
}

我想到了一些选择。一种是控制器方法生成所有内容类型,然后在方法中抛出异常。如果内容类型不是您期望的类型,则异常处理程序可以接受该异常并对其进行转换。这是唯一一个与异常处理程序一起工作的异常处理程序,因为异常处理程序只处理控制器方法中产生的异常

其他选择包括:

  • 使用拦截器(但我不确定这是否有效,因为Spring可能会首先尝试解析控制器方法,而不是调用拦截器)
  • 扩展
    RequestMappingHandlerMapping
    以在异常处理程序找不到合适的方法时调用异常处理程序。您可能需要重写方法
    handleNoMatch
    。在这里,您需要获得对
    HandlerExceptionResolver

第一个是最容易理解的,而最新的可能是最“可扩展”的,但这也需要对Spring的内部结构有一些了解。

通过为
异常处理程序设置不同的内容协商策略
固定内容协商策略
HeaderContentNegotiationStrategy
RequestResponseBodyMethodProcessor
设置不同的内容协商策略来解决快速响应。如果您没有注意到,我正在扩展ResponseEntityExceptionHandler,这样我可以将错误消息添加到响应的主体中,并且我已经重写了受保护的方法,所以所有异常都可以写为错误消息。然后,Spring消息转换器将内容类型解析为application/json;字符集=UTF-8或应用程序/*+json;charset=UTF-8,基于返回值(本例中为我的错误消息对象),并与accept标头类型(application/xml)进行比较,在写入响应时再次抛出HttpMediaTypeNotAcceptableException。是的,实际上问题是即使调用了ExceptionHandler并返回自定义错误对象,spring再次尝试根据可产生和可接受的类型(AbstractMessageConverterMethodProcessor内部)查找响应类型。如果请求的mime类型可生成(即HttpMessageConverter)可用于该类型,则ExceptionHandler返回的自定义错误对象将按照Accept标头写入响应,否则spring将退回到HTML