繁体   English   中英

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

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

Spring 3.2引入了@ControllerAdvice注释来处理Spring MVC应用程序中的异常。 但在此版本之前,Spring使用@ExceptionHandlerHandlerExceptionResolver来处理Spring MVC应用程序中的异常。 那么为什么Spring 3.2引入了@ControllerAdvice注释来处理异常呢? 我坚信Spring 3.2引入了@ControllerAdvice注释来解决 @ExceptionHandlerHandlerExceptionResolver 的局限性,或者使异常处理更加强大

任何人都能解释@ControllerAdvice优于@ExceptionHandlerHandlerExceptionResolver处理异常的优势吗?

@ExceptionHandler

@ExceptionHandlerController级别工作 ,它仅对该特定Controller有效,而不是整个应用程序的全局。

HandlerExceptionResolver

这将解决应用程序抛出的任何异常。 它用于将标准Spring异常解析为其相应的HTTP状态代码 它无法控制响应的主体,意味着它不会对响应的主体设置任何内容。它会在响应中映射状态代码,但正文为空

@ControllerAdvice

@ControllerAdvice用于Spring MVC应用程序中的全局错误处理。它还可以完全控制响应的主体和状态代码。

@ExceptionHandler是控制器的本地:只有来自此控制器的异常才会路由到他的@ExceptionHandler

@ControllerAdvice是全局的:您可以使用集中的方式来处理异常,绑定等,它适用于所有已定义的控制器。

区别在于:如果我需要配置异常处理代码,那么我需要在我的项目中使用@ExceptionHandler注释,它可以在两个diff.ways中使用: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)如果我创建一个扩展ResponseEntityExceptionHandler(SpringBoot类)的新类,并且如果我使用@ControllerAdvice注释它,则该类变为globalexceptionhandler,这意味着可以在此处处理任何导致任何控制器类的异常。 它可以出现在同一个项目的任何包中。

@RestController
@ControllerAdvice
public class GlobalJavaExceptionHandler extends ResponseEntityExceptionHandler{

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

如果两者都存在于代码中,那么本地优先于全局代码。 理想情况下,第二个选项是更好的选项,因为我们不需要在每个控制器类中添加代码,并且使用@ControllerAdvice这个类可以是一站式解决方案,用于因控制器到控制器的代码而产生的所有异常代码的长度。

@ExceptionHandler可以在本地级别或全局级别使用。 本地级别意味着在控制器本身内使用此注释来仅处理该控制器内的异常。 该控制器抛出的所有错误都将被@ExceptionHandler捕获。 但这意味着如果在不同的控制器中存在类似的异常,则必须在本地再次在该控制器中重写相应的代码。

为了防止每个控制器重复这种类型的异常处理,我们可以在另一个名为@ControllerAdvice的注释的帮助下在全局级别编写@ExceptionHanlder。

@ControllerAdvice不是特定于异常处理的,它还用于在全局级别处理属性,验证或格式化程序绑定。 异常处理上下文中的@ControllerAdvice只是使用@Exceptionhandler注释在全局级别进行异常处理的另一种方法。

现在来到HandlerExceptionResolver - 这是一个更低级别的接口。 Spring提供了2个实现:

  • ResponseStatusExceptionResolver:这支持@ResponseStatus注释的支持
  • ExceptionHandlerExceptionResolver:这支持@ExceptionHandler注释

示例:因此,当您想要处理异常并选择异常处理策略时,您需要考虑在通过注释使用本地或全局异常处理之间进行选择。 您需要如何提供HTTP状态代码,如何将其包装在@Response实体中,如何重定向到处理程序页面,通过flash属性传送数据或获取参数等等。或者可以跳过注释并使用SimpleMappingExceptionResolver并开始将特定异常映射到错误处理程序页面URL

在这里,我们不会考虑在此阶段使用HandlerExceptionResolver的较低级别,因为我们正在处理更高级别的实现并基于这些选项构建策略。

使用上面的上下文来回答你的查询 - @ControllerAdvice没有引入异常处理,它是一种可以利用@ExceptionHandler全局处理异常的机制。 HandlerExceptionResolver是一个接口,其实现有助于支持@ResponseStatus和@Exceptionhandler注释。 除非您想要处理与MVC系统相关的异常,否则Spring框架不提供任何适当的异常处理。 因此,如果您需要处理;与错误的@Requestmapping等相关的问题,这些问题不会被控制器捕获,因为它甚至无法在第一个位置到达它,那么HandlerExceptionResolver的实现将是有用的

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM