代码之家  ›  专栏  ›  技术社区  ›  ioreskovic

在Spring中为异常处理定制@controlleradvice

  •  2
  • ioreskovic  · 技术社区  · 7 年前

    我正在尝试将异常从我的休息控制器映射到具有身体的响应,并在中心位置执行。

    我尝试过:

    @Order(Ordered.HIGHEST_PRECEDENCE)
    @ControllerAdvice
    public class RestErrorResponseExceptionHandler extends ResponseEntityExceptionHandler {
        @Override
        protected ResponseEntity<Object> handleExceptionInternal(
            Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
            super.handleExceptionInternal(ex, body, headers, status, request);
    
            return ResponseEntity.status(status).body(Error.from(status));
        }
    } 
    

    问题是处理程序永远不会被触发。

    如果我用 @ExceptionHandler 在我的休息控制器中,或者扩展 @异常处理程序 ,然后所有的工作都很好,但这会引入一些糟糕的设计。

    据我所知,Spring将首先尝试在控制器中查找异常处理方法,然后检查注册的处理程序。

    我试图通过WebMVCTest验证行为,得到的响应不是我所期望的错误对象。

    我有什么东西不见了吗?

    3 回复  |  直到 7 年前
        1
  •  2
  •   yohann henry Yohann    7 年前

    控制器建议是必须由Spring注册的配置。您必须在配置包中移动类,或者您可以通过注释来注册它。

    在我的例子中,我使用的是像这样的控制器建议:

    @ControllerAdvice
    public class GlobalControllerExceptionHandler {
    
        @ExceptionHandler(MyException.class) 
        public ResponseEntity<String> reponseMyException(Exception e) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body("my message");
        }
    }
    
        2
  •  2
  •   0gam    7 年前

    Spring框架提供了以下方法来帮助我们实现健壮的异常处理。

    1. 基于控制器 我们可以在控制器类中定义异常处理程序方法。我们只需要用@exceptionhandler注释来注释这些方法。此批注将异常类作为参数。因此,如果我们为异常类定义了其中一个,那么由请求处理程序方法抛出的所有异常都将得到处理。 这些异常处理程序方法与其他请求处理程序方法一样,我们可以构建错误响应并使用不同的错误页进行响应。我们还可以发送JSON错误响应,稍后我们将在示例中查看。 如果定义了多个异常处理程序方法,则使用最接近异常类的处理程序方法。例如,如果我们为IOException和Exception定义了两个处理程序方法,并且我们的请求处理程序方法抛出IOException,那么IOException的处理程序方法将被执行。

    2. 全局异常处理程序 异常处理是一个横切问题,应该针对应用程序中的所有切入点进行处理。我们已经研究了SpringAOP,这就是为什么Spring提供了@ControllerAdvice注释,我们可以用它来定义全局异常处理程序。 全局控制器建议中的处理程序方法与基于控制器的异常处理程序方法相同,并且在控制器类无法处理异常时使用。

    3. 处理程序异常解析程序 _“对于一般例外,大多数情况下我们提供静态页面。Spring框架提供了handlerExceptionResolver接口,我们可以实现它来创建全局异常处理程序。这种定义全局异常处理程序的额外方法背后的原因是SpringFramework还提供了默认的实现类,我们可以在SpringBean配置文件中定义这些实现类,以获得SpringFramework异常处理的好处。 SimpleMappingExceptionResolver是默认的实现类,它允许我们配置ExceptionMappings,在这里我们可以指定用于特定异常的资源。我们还可以重写它,用特定于应用程序的更改(如异常消息的日志记录)创建自己的全局处理程序。

        3
  •  1
  •   laffuste user5637641    5 年前

    确保有两件事,你的代码就可以工作了。

    1. 你的 @ControllerAdvice 类在组件扫描路径中可用。
    2. 确保您的 @管制员建议 有点像这样的结构-
        @ExceptionHandler(value = { RequestProcessingException.class })
        public @ResponseBody ResponseEntity<ErrorMessageBO> hotelConfigServiceExceptionHandler(HttpServletRequest request, RequestProcessingException e) {
           logger.error("Exception with tracking Id: {}, dev message: {} and Message:", RequestContextKeeper.getContext().getRequestId(), e.getDeveloperMessage(),e);
           return new ResponseEntity<ErrorMessageBO>(new ErrorMessageBO(e.getErrorCode(), e.getMessage(),RequestContextKeeper.getContext().getRequestId(),e.getDeveloperMessage()), HttpStatus.OK);
        }