java @ControllerAdvice 在处理异常方面比 @ExceptionHandler 或 HandlerExceptionResolver 有什么优势?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35323174/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions?
提问by Rajorshi Roy
Spring 3.2introduced @ControllerAdvice
annotation for handling exceptions in a Spring MVC application. But prior to this version Spring had @ExceptionHandler
or HandlerExceptionResolver
to handling exceptions in a Spring MVC application. Then why Spring 3.2introduced @ControllerAdvice
annotation for handling exceptions? I strongly believe that Spring 3.2introduced @ControllerAdvice
annotation to address the limitations of@ExceptionHandler
or HandlerExceptionResolver
or make the exceptions handling more stronger.
Spring 3.2引入了@ControllerAdvice
用于在 Spring MVC 应用程序中处理异常的注解。但在此版本之前,Spring 已经@ExceptionHandler
或HandlerExceptionResolver
将处理 Spring MVC 应用程序中的异常。那么为什么Spring 3.2引入@ControllerAdvice
了处理异常的注解呢?我坚信,春3.2引入了@ControllerAdvice
注释,以解决限制@ExceptionHandler
或HandlerExceptionResolver
或使例外处理更强。
Can any one explain the advantages of @ControllerAdvice
over @ExceptionHandler
or HandlerExceptionResolver
for handling exceptions?
任何人都可以解释@ControllerAdvice
over@ExceptionHandler
或HandlerExceptionResolver
for processing exceptions的优点吗?
回答by Bacteria
@ExceptionHandler
@ExceptionHandler
@ExceptionHandler
works at the Controller leveland it is only active for that particular Controller,not globally for the entire application.
@ExceptionHandler
在控制器级别工作,它只对特定的控制器有效,而不是对整个应用程序全局有效。
HandlerExceptionResolver
处理异常解析器
This will resolve any exception thrown by the application. It is used to resolve standard Spring exceptions to their corresponding HTTP Status Codes. 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.
这将解决应用程序抛出的任何异常。它用于将标准 Spring 异常解析为相应的 HTTP 状态代码。它无法控制响应的正文,这意味着它不会为 Response 的正文设置任何内容。它确实将状态代码映射到响应上,但正文为 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 应用程序中的全局错误处理。它还可以完全控制响应的主体和状态代码。
回答by Jérémie B
A @ExceptionHandler
is local to a controller : only exceptions from this controller is routed to his @ExceptionHandler
A@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.
但是 a@ControllerAdvice
是全局的:你可以有一个集中的方式来处理异常、绑定等。它适用于所有定义的控制器。
回答by Mohammed Amen
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. for eg:
区别如下:如果我需要配置异常处理代码,那么我需要在我的项目中使用@ExceptionHandler 注释,它可以在两种不同的方式中使用:1)使用注释并在本地处理同一个控制器中的异常在每个控制器类中。例如:
@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. And it can be present in any package in the same project.
2)如果我创建一个扩展 ResponseEntityExceptionHandler(SpringBoot class) 的新类,并且如果我使用 @ControllerAdvice 对其进行注释,那么该类将成为 globalexceptionhandler,这意味着可以在此处处理导致任何控制器类的任何异常。它可以出现在同一个项目的任何包中。
@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 的类可以是一个一站式解决方案,用于解决由于代码从控制器到 dao 的所有异常。代码的长度。
回答by Chetan Handa
@ExceptionHandler can be used at the local level or at the global level. 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. 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.
@ExceptionHandler 可以在本地级别或全局级别使用。本地级别意味着在控制器本身内使用此注释来仅处理该控制器内的异常。该控制器抛出的所有错误都将被该@ExceptionHandler 捕获。但这意味着如果在不同的控制器中存在类似的异常,您将不得不在该控制器中再次在本地重新编写相应的代码。
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 in the context of exception handling is just another way of doing exception handling at a global level using @Exceptionhandler annotation.
@ControllerAdvice 并不特定于异常处理,它也用于处理全局级别的属性、验证或格式化程序绑定。@ControllerAdvice 在异常处理的上下文中只是使用 @Exceptionhandler 注释在全局级别进行异常处理的另一种方式。
Now coming to the HandlerExceptionResolver - this is an interface at a more lower level. Spring provides 2 implementations of this:
现在来到 HandlerExceptionResolver - 这是一个更低级别的接口。Spring 提供了 2 种实现:
- ResponseStatusExceptionResolver :This supports the support the @ResponseStatus annotation
- ExceptionHandlerExceptionResolver : This supports the @ExceptionHandler annotation
- ResponseStatusExceptionResolver : 支持@ResponseStatus注解
- 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. HandlerExceptionResolver is an interface whose implementation helps support the @ResponseStatus and the @Exceptionhandler annotations. Unless you want to handle the exceptions related to the MVC system because the Spring framework does not provide any proper exception handling. 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
使用上述上下文来回答您的查询- @ControllerAdvice 没有被引入用于异常处理,它是一种您可以利用@ExceptionHandler 全局处理异常的机制。HandlerExceptionResolver 是一个接口,其实现有助于支持@ResponseStatus 和@Exceptionhandler 注释。除非你想处理与MVC系统相关的异常,因为Spring框架没有提供任何适当的异常处理。因此,如果您需要处理与不正确的 @Requestmapping 等相关的问题,这些问题不会被控制器捕获,因为它甚至不会在第一个位置到达它,那么 HandlerExceptionResolver 的实现将是有用的