简体   繁体   English

@ControllerAdvice优于@ExceptionHandler或HandlerExceptionResolver处理异常的优点是什么?

[英]What are the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions?

Spring 3.2 introduced @ControllerAdvice annotation for handling exceptions in a Spring MVC application. Spring 3.2引入了@ControllerAdvice注释来处理Spring MVC应用程序中的异常。 But prior to this version Spring had @ExceptionHandler or HandlerExceptionResolver to handling exceptions in a Spring MVC application. 但在此版本之前,Spring使用@ExceptionHandlerHandlerExceptionResolver来处理Spring MVC应用程序中的异常。 Then why Spring 3.2 introduced @ControllerAdvice annotation for handling exceptions? 那么为什么Spring 3.2引入了@ControllerAdvice注释来处理异常呢? I strongly believe that Spring 3.2 introduced @ControllerAdvice annotation to address the limitations of @ExceptionHandler or HandlerExceptionResolver or make the exceptions handling more stronger . 我坚信Spring 3.2引入了@ControllerAdvice注释来解决 @ExceptionHandlerHandlerExceptionResolver 的局限性,或者使异常处理更加强大

Can any one explain the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions? 任何人都能解释@ControllerAdvice优于@ExceptionHandlerHandlerExceptionResolver处理异常的优势吗?

@ExceptionHandler @ExceptionHandler

@ExceptionHandler works at the Controller level and it is only active for that particular Controller, not globally for the entire application. @ExceptionHandlerController级别工作 ,它仅对该特定Controller有效,而不是整个应用程序的全局。

HandlerExceptionResolver HandlerExceptionResolver

This will resolve any exception thrown by the application. 这将解决应用程序抛出的任何异常。 It is used to resolve standard Spring exceptions to their corresponding HTTP Status Codes . 它用于将标准Spring异常解析为其相应的HTTP状态代码 It does not have control over the body of the response, means it does not set anything to the body of the Response .It does map the status code on the response but the body is null . 它无法控制响应的主体,意味着它不会对响应的主体设置任何内容。它会在响应中映射状态代码,但正文为空

@ControllerAdvice @ControllerAdvice

@ControllerAdvice used for global error handling in the Spring MVC application.It also has full control over the body of the response and the status code. @ControllerAdvice用于Spring MVC应用程序中的全局错误处理。它还可以完全控制响应的主体和状态代码。

A @ExceptionHandler is local to a controller : only exceptions from this controller is routed to his @ExceptionHandler @ExceptionHandler是控制器的本地:只有来自此控制器的异常才会路由到他的@ExceptionHandler

But a @ControllerAdvice is global : you can have a centralized way to handle exceptions, binding, etc. it applies to all the defined controller. @ControllerAdvice是全局的:您可以使用集中的方式来处理异常,绑定等,它适用于所有已定义的控制器。

Here is the difference: If I need to configure the exception handling code then I need to use @ExceptionHandler annotation in my project which can be used in two diff.ways: 1)To use the annotation and handle the exception in the same controller locally in each controller class. 区别在于:如果我需要配置异常处理代码,那么我需要在我的项目中使用@ExceptionHandler注释,它可以在两个diff.ways中使用:1)使用注释并在本地处理同一个控制器中的异常在每个控制器类中。 for eg: 例如:

@RestController
public class WSExposingController{

@GetMapping("/getAllDetails/{/id}")
public UserDetails myMethod(@PathVariable int id){
UserDetails user = UserDetailsService.getUser(id);
return user;
}

//To handle the exceptions which are resulting from this controller, I can declare an exceptionHandler specifically in the same class

@ExceptionHandler(Exception.class)
public ResponseEntity handlerSameControllerExceptions(){
return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);

}

} }

2)If I create a new class which extends ResponseEntityExceptionHandler(SpringBoot class) and if I ANNOTATE IT WITH @ControllerAdvice then that class becomes globalexceptionhandler meaning to say that any exception which is resulting in any controller class can be handled here. 2)如果我创建一个扩展ResponseEntityExceptionHandler(SpringBoot类)的新类,并且如果我使用@ControllerAdvice注释它,则该类变为globalexceptionhandler,这意味着可以在此处处理任何导致任何控制器类的异常。 And it can be present in any package in the same project. 它可以出现在同一个项目的任何包中。

@RestController
@ControllerAdvice
public class GlobalJavaExceptionHandler extends ResponseEntityExceptionHandler{

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleDiffControllerExceptions(){
        return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);
    }

If both are present in the code then the local with take precedence over the global one. 如果两者都存在于代码中,那么本地优先于全局代码。 Ideally the second option is a better one as we need not add the code in each and every controller class and this class with @ControllerAdvice can be a one stop solution for all the exceptions arising due to the code beginning from the controller to the dao throughout the length of the code. 理想情况下,第二个选项是更好的选项,因为我们不需要在每个控制器类中添加代码,并且使用@ControllerAdvice这个类可以是一站式解决方案,用于因控制器到控制器的代码而产生的所有异常代码的长度。

@ExceptionHandler can be used at the local level or at the global level. @ExceptionHandler可以在本地级别或全局级别使用。 Local level would mean using this annotation within the controller itself to handle the exceptions within that controller only. 本地级别意味着在控制器本身内使用此注释来仅处理该控制器内的异常。 All error thrown by that controller would be caught by that @ExceptionHandler. 该控制器抛出的所有错误都将被@ExceptionHandler捕获。 But this would mean that if there is a similar exception in a different controller you would have to rewrite the corresponding code again in that controller again locally. 但这意味着如果在不同的控制器中存在类似的异常,则必须在本地再次在该控制器中重写相应的代码。

In order to prevent repeating this style of exception handling per controller we can write the @ExceptionHanlder at the global level with the help of another annotation called @ControllerAdvice. 为了防止每个控制器重复这种类型的异常处理,我们可以在另一个名为@ControllerAdvice的注释的帮助下在全局级别编写@ExceptionHanlder。

@ControllerAdvice is not specific to the exception handling , its also used for handling property, validation or formatter bindings at the global level. @ControllerAdvice不是特定于异常处理的,它还用于在全局级别处理属性,验证或格式化程序绑定。 @ControllerAdvice in the context of exception handling is just another way of doing exception handling at a global level using @Exceptionhandler annotation. 异常处理上下文中的@ControllerAdvice只是使用@Exceptionhandler注释在全局级别进行异常处理的另一种方法。

Now coming to the HandlerExceptionResolver - this is an interface at a more lower level. 现在来到HandlerExceptionResolver - 这是一个更低级别的接口。 Spring provides 2 implementations of this: Spring提供了2个实现:

  • ResponseStatusExceptionResolver :This supports the support the @ResponseStatus annotation ResponseStatusExceptionResolver:这支持@ResponseStatus注释的支持
  • ExceptionHandlerExceptionResolver : This supports the @ExceptionHandler annotation ExceptionHandlerExceptionResolver:这支持@ExceptionHandler注释

Example : So when you want to handle exceptions and choose an exception handling strategy you will need to think of choosing between using a local or global exception handling via the annotations. 示例:因此,当您想要处理异常并选择异常处理策略时,您需要考虑在通过注释使用本地或全局异常处理之间进行选择。 How you need to provide the HTTP status codes, how to wrap it in the @Response entity etc, how you want to redirect to handler pages , carry the data via flash attributes or get params etc etc. Or maybe skip the annotations and use the SimpleMappingExceptionResolver and start mapping the specific exceptions to the error handler page urls 您需要如何提供HTTP状态代码,如何将其包装在@Response实体中,如何重定向到处理程序页面,通过flash属性传送数据或获取参数等等。或者可以跳过注释并使用SimpleMappingExceptionResolver并开始将特定异常映射到错误处理程序页面URL

Here we are not be considering the lower level underlying HandlerExceptionResolver at this stage since we are dealing with its implementation at a higher level and building the strategy based on these options. 在这里,我们不会考虑在此阶段使用HandlerExceptionResolver的较低级别,因为我们正在处理更高级别的实现并基于这些选项构建策略。

With the above context to answer your query - @ControllerAdvice was not introduced for exception handling, it's a mechanism you can leverage to handle exceptions globally using the @ExceptionHandler. 使用上面的上下文来回答你的查询 - @ControllerAdvice没有引入异常处理,它是一种可以利用@ExceptionHandler全局处理异常的机制。 HandlerExceptionResolver is an interface whose implementation helps support the @ResponseStatus and the @Exceptionhandler annotations. HandlerExceptionResolver是一个接口,其实现有助于支持@ResponseStatus和@Exceptionhandler注释。 Unless you want to handle the exceptions related to the MVC system because the Spring framework does not provide any proper exception handling. 除非您想要处理与MVC系统相关的异常,否则Spring框架不提供任何适当的异常处理。 So if you need to hand;e issues related to incorrect @Requestmapping etc which would not be caught by a controller as it would not even reach it in the 1st place then an implementation of the HandlerExceptionResolver would be useful 因此,如果您需要处理;与错误的@Requestmapping等相关的问题,这些问题不会被控制器捕获,因为它甚至无法在第一个位置到达它,那么HandlerExceptionResolver的实现将是有用的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 @ControllerAdvice 和 @ExceptionHandler 不捕获异常 - @ControllerAdvice with @ExceptionHandler don't catch exceptions Spring MVC,将@ExceptionHandler迁移到HandlerExceptionResolver以获取RESTful服务 - Spring MVC, Migrate @ExceptionHandler to HandlerExceptionResolver for a RESTful service Spring ControllerAdvice ExceptionHandler不起作用 - Spring ControllerAdvice ExceptionHandler does not work @ExceptionHandler(Exception.class)不处理所有类型的异常 - @ExceptionHandler(Exception.class) not handling all types of exceptions 与@RequestParam相比,@ MatrixVariable有什么优势? - What are the advantages of @MatrixVariable over @RequestParam? TLongArrayList 比 long[] 有什么优势 - What are the advantages of TLongArrayList over long[] @ControllerAdvice 和 @ExceptionHandler 没有被我的 RestController 触发 - @ControllerAdvice and @ExceptionHandler not getting triggered for my RestController RestController 中的 ControllerAdvice、ExceptionHandler 和 try catch 块 - ControllerAdvice, ExceptionHandler and try catch block in RestController @ControllerAdvice 或 @ExceptionHandler 都不适用于 gradle 项目 - @ControllerAdvice or @ExceptionHandler both not working on gradle project 如何在ControllerAdvice中使用ExceptionHandler处理控制器中ExceptionHandler抛出的异常? - How to handle exception thrown from ExceptionHandler in controller with ExceptionHandler in ControllerAdvice?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM