【问题标题】:spring boot override default REST exception handlerspring boot 覆盖默认的 REST 异常处理程序
【发布时间】:2016-06-04 11:44:05
【问题描述】:

我无法覆盖 REST api 中的默认 Spring Boot 错误响应。我有以下代码

@ControllerAdvice
@Controller
class ExceptionHandlerCtrl {

    @ResponseStatus(value=HttpStatus.UNPROCESSABLE_ENTITY, reason="Invalid data")
    @ExceptionHandler(BusinessValidationException.class)
    @ResponseBody
    public ResponseEntity<BusinessValidationErrorVO> handleBusinessValidationException(BusinessValidationException exception){
        BusinessValidationErrorVO vo = new BusinessValidationErrorVO()
        vo.errors = exception.validationException
        vo.msg = exception.message
        def result =  new ResponseEntity<>(vo, HttpStatus.UNPROCESSABLE_ENTITY);
        result

    }

然后在我的 REST api 中我抛出这个 BusinessValidationException。这个处理程序被调用(我可以在调试器中看到它)但是我仍然收到默认的 spring boot REST 错误消息。有没有办法覆盖和使用默认作为后备?带有 groovy 的 Spring Boot 版本 1.3.2。最好的问候

【问题讨论】:

    标签: spring rest groovy spring-boot


    【解决方案1】:

    从您的方法中删除 @ResponseStatus。它会产生不良副作用,您不需要它,因为您在 ResponseEntity 中设置了 HttpStatus.UNPROCESSABLE_ENTITY

    来自JavaDoc on ResponseStatus

    警告:在异常类上使用该注解,或设置该注解的原因属性时,将使用HttpServletResponse.sendError方法。

    对于HttpServletResponse.sendError,响应被认为是完整的,不应再写入任何内容。此外,Servlet 容器通常会编写一个 HTML 错误页面,因此会使用不适合 REST API 的原因。对于这种情况,最好使用ResponseEntity 作为返回类型,并完全避免使用@ResponseStatus

    【讨论】:

      【解决方案2】:

      我建议你阅读这个问题:Spring Boot REST service exception handling

      您可以在此处找到一些示例,说明如何结合 ErrorController/ ControllerAdvice 以捕获任何异常。

      特别检查这个答案:

      https://stackoverflow.com/a/28903217/379906

      您可能应该从方法 handleBusinessValidationException 中删除注释 @ResponseStatus

      另一种重写默认错误消息的方法是使用带有注解@RequestMapping("/error") 的控制器。控制器必须实现 ErrorController 接口。

      这是我在应用中使用的错误控制器。

      @RestController
      @RequestMapping("/error")
      public class RestErrorController implements ErrorController
      {
          private final ErrorAttributes errorAttributes;
      
          @Autowired
          public MatemoErrorController(ErrorAttributes errorAttributes) {
              Assert.notNull(errorAttributes, "ErrorAttributes must not be  null");
          this.errorAttributes = errorAttributes;
        }
      
      @Override
      public String getErrorPath() {
          return "/error";
      }
      
      @RequestMapping
      public Map<String, Object> error(HttpServletRequest aRequest) {
      
          return getErrorAttributes(aRequest, getTraceParameter(aRequest));
      }
      
      private boolean getTraceParameter(HttpServletRequest request) {
          String parameter = request.getParameter("trace");
          if (parameter == null) {
              return false;
          }
          return !"false".equals(parameter.toLowerCase());
      }
      
      private Map<String, Object> getErrorAttributes(HttpServletRequest  aRequest, boolean includeStackTrace)
      {
          RequestAttributes requestAttributes = new  ServletRequestAttributes(aRequest);
          return errorAttributes.getErrorAttributes(requestAttributes,  includeStackTrace);
      }  }
      

      【讨论】:

        猜你喜欢
        • 2020-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-29
        • 2016-04-13
        • 2020-01-20
        • 2017-05-02
        相关资源
        最近更新 更多