zoukankan      html  css  js  c++  java
  • @ControllerAdvice全局异常处理

    @ControllerAdvice是Spring提供的注释,使您可以编写可应用于各种控制器的全局代码-从所有控制器到选定的包,甚至是特定的注释。在这个简短的教程中,我们将专注于处理异常使用@ControllerAdvice和@ExceptionHandler(@InitBinder和@ModalAttribute也可以使用@ControllerAdvice)。

    使用如下依赖进行测试:

    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-hateoas</artifactId>
    </dependency>

    对于hateoas的相关介绍,可以看看这篇文章https://blog.csdn.net/w57685321/article/details/82894803

    默认情况下,  @ControllerAdvice将应用于使用@Controller注释的所有类(扩展到使用的类@RestController)。如果您想更具体一点,可以使用一些属性来实现这一点。

    要按包减少适用的类,您只需要将包的名称添加到注释中。选择一个程序包后,将为该程序包内的子类以及子程序包启用该程序包。也可以按照相同的过程选择多个包,但是使用数组而不是单个字符串(其中的所有属性都@ControllerAdvice可以是单个或多个)。

    @ControllerAdvice("my.chosen.package")
    @ControllerAdvice(value = "my.chosen.package")
    @ControllerAdvice(basePackages = "my.chosen.package")

    可以通过basePackageClasses属性来指定包,该属性将使@ControllerAdvice类(或接口)所在的包中的所有控制器都可用。

    如果要指定特定的类,可以通过@ControllerAdvice(assignableTypes = MyController.class)来指定。

    如果要应用于某些带注释的控制器,可以使用  @ControllerAdvice(annotations = RestController.class) ,此处仅对RestController起作用,而不会对带controller的起作用,尽管RestControlle注解相当于@ResponseBody + @Controller。

    @ExceptionHandler顾名思义,您可以定义一个处理异常的方法。如果您不使用@ControllerAdvice ,则处理这些异常的代码将在控制器本身中,这可能会给类增加很多重复和混乱,并导致其不那么“干净”。您可以将这些@ExceptionHandler方法移到控制器扩展以分离代码的基类中。此方法并不完美,并且存在一个问题,即您需要此全局异常处理的每个控制器现在都需要扩展基本控制器。因此,当您创建一个新的控制器而忘记扩展此基类时,您现在不再处理某些异常,以后可能会陷入困境。使用@ControllerAdvice@ExceptionHandler 通过提供全局(更具体的)错误处理来防止这种情况的发生,因此您无需记住自己实现它们或每次扩展另一个类。

    示例:

    @ControllerAdvice @RequestMapping(produces = "application/vnd.error+json") public class PersonControllerAdvice {
        @ExceptionHandler(PersonNotFoundException.class) public ResponseEntity < VndErrors > notFoundException(final PersonNotFoundException e) {
            return error(e, HttpStatus.NOT_FOUND, e.getId().toString());
        }
        private ResponseEntity < VndErrors > error(final Exception exception, final HttpStatus httpStatus, final String logRef) {
            final String message = Optional.of(exception.getMessage()).orElse(exception.getClass().getSimpleName());
            return new ResponseEntity < > (new VndErrors(logRef, message), httpStatus);
        }
        @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity < VndErrors > assertionException(final IllegalArgumentException e) {
            return error(e, HttpStatus.NOT_FOUND, e.getLocalizedMessage());
        }
    }

    此类@ExceptionHandler为所有控制器全局提供了方法,因为(单独从此代码中看不到)有多个throw的控制器PersonNotFoundException需要处理。RequestMapping此处的注释用于设置所返回的内容类型ResponseEntity。这些可以添加到方法本身,而不是需要返回的不同类型。每个@ExceptionHandler标记实例都负责处理一个异常。本示例中的方法仅捕获异常并获取其错误消息,然后将其与适当的响应代码组合在一起。

     @ExceptionHandler为同一异常定义了多个对象  ,需要进行监视。当在同一类中定义时,Spring足以引发异常并在启动时失败。但是,当它们出现在不同的类中时,例如说两个@ControllerAdvice类,都带有的处理程序PersonNotFoundException,应用程序将启动-但将使用找到的第一个处理程序。如果您不知道,这可能会导致意外的行为。

    不经一番彻骨寒,哪有梅花扑鼻香?
  • 相关阅读:
    Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier 's'
    抓报错SQL
    10.3.4 direct path read and direct path read temp
    武道与健身——北漂18年(80)
    jquery选择器 之 获取父级元素、同级元素、子元素
    JQuery Show()的几种效果 总有一种是你需要的
    Add method not implemented
    MySQL server version for the right syntax to use near 'info where info.stu_id = 1' at line 1
    Mapped Statements collection does not contain value for WaitMissionMapper.updateWait
    Cause: org.xml.sax.SAXParseException; lineNumber: 32; columnNumber: 14; 注释中不允许出现字符串 "--"
  • 原文地址:https://www.cnblogs.com/zongyao/p/13831085.html
Copyright © 2011-2022 走看看