zoukankan      html  css  js  c++  java
  • @ControllerAdvice和@ExceptionHandler

    1. 使用 @ControllerAdvice和@ExceptionHandler处理全局异常

    1. 新建异常信息实体类

    非必要的类,主要用于包装异常信息。

     1 package com.test.exception.myexception;
     2 
     3 public class ErrorResponse {
     4     private String message;
     5     private String errorTypeName;
     6 
     7     public ErrorResponse(Exception e) {
     8         this(e.getClass().getName(), e.getMessage());
     9     }
    10 
    11     public ErrorResponse(String errorTypeName, String message) {
    12         this.errorTypeName = errorTypeName;
    13         this.message = message;
    14     }
    15 
    16     public String getMessage() {
    17         return message;
    18     }
    19 
    20     public void setMessage(String message) {
    21         this.message = message;
    22     }
    23 
    24     public String getErrorTypeName() {
    25         return errorTypeName;
    26     }
    27 
    28     public void setErrorTypeName(String errorTypeName) {
    29         this.errorTypeName = errorTypeName;
    30     }
    31 }

    2. 自定义异常类型

    package com.test.exception.myexception;
    
    public class ReourceNotFoundException extends RuntimeException {
        private String message;
    
        public ReourceNotFoundException() {
            super();
        }
    
        public ReourceNotFoundException(String message) {
            super(message);
            this.message = message;
        }
    
        @Override
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }

    3. 新建异常处理类

    我们只需要在类上加上@ControllerAdvice注解这个类就成为了全局异常处理类,当然你也可以通过 assignableTypes指定特定的 Controller类,让异常处理类只处理特定类抛出的异常。

     1 package com.test.exception.handler;
     2 
     3 
     4 import com.test.exception.myexception.ErrorResponse;
     5 import com.test.exception.myexception.ReourceNotFoundException;
     6 import org.springframework.http.ResponseEntity;
     7 import org.springframework.web.bind.annotation.ControllerAdvice;
     8 import org.springframework.web.bind.annotation.ExceptionHandler;
     9 import org.springframework.web.bind.annotation.ResponseBody;
    10 import org.springframework.web.server.ResponseStatusException;
    11 
    12 @ControllerAdvice(assignableTypes = {com.test.exception.controller.ExceptionController.class})
    13 @ResponseBody
    14 public class GlobalExceptionHandler {
    15     ErrorResponse illegalArgumentResponse = new ErrorResponse(new IllegalArgumentException("参数错误!"));
    16     ErrorResponse resourseNotFoundResponse = new ErrorResponse(new com.test.exception.myexception.ReourceNotFoundException("Sorry, the resourse not found!"));
    17 
    18 
    19     @ExceptionHandler(value = Exception.class)// 拦截所有异常, 这里只是为了演示,一般情况下一个方法特定处理一种异常
    20     public ResponseEntity<ErrorResponse> exceptionHandler(Exception e) {
    21 
    22         if (e instanceof IllegalArgumentException) {
    23             return ResponseEntity.status(400).body(illegalArgumentResponse);
    24         } else if (e instanceof ReourceNotFoundException) {
    25             return ResponseEntity.status(404).body(resourseNotFoundResponse);
    26         }else if(e instanceof ResponseStatusException){
    27             return ResponseEntity.status(502).body(resourseNotFoundResponse);
    28         }
    29         return null;
    30     }
    31 }

    4. controller模拟抛出异常

     1 package com.test.exception.controller;
     2 
     3 import com.test.exception.myexception.ReourceNotFoundException;
     4 import org.springframework.http.HttpStatus;
     5 import org.springframework.web.bind.annotation.GetMapping;
     6 import org.springframework.web.bind.annotation.RestController;
     7 import org.springframework.web.server.ResponseStatusException;
     8 
     9 @RestController
    10 public class ExceptionController {
    11 
    12     @GetMapping("/illegalArgumentException")
    13     public void throwException() {
    14         throw new IllegalArgumentException();
    15     }
    16 
    17     @GetMapping("/resourceNotFoundException")
    18     public void throwException2() {
    19         throw new ReourceNotFoundException();
    20 
    21     }
    22 
    23     @GetMapping("/resourceNotFoundException2")
    24     public void throwException3() {
    25         throw new ResponseStatusException(HttpStatus.BAD_GATEWAY,"The resource not found",new ReourceNotFoundException());
    26     }
    27 }

    使用 Get 请求: http://localhost:8080/resourceNotFoundException

    {"message":"Sorry, the resourse not found!","errorTypeName":"com.test.exception.myexception.ReourceNotFoundException"}

    3. ResponseStatusException

    研究 ResponseStatusException 我们先来看看,通过 ResponseStatus注解简单处理异常的方法(将异常映射为状态码)。

    package com.test.exception.myexception;
    
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    @ResponseStatus(code = HttpStatus.BAD_GATEWAY)
    public class ReourceNotFoundException2 extends RuntimeException {
        public ReourceNotFoundException2() {
        }
    
        public ReourceNotFoundException2(String message) {
            super(message);
        }
    }

    这种通过 ResponseStatus注解简单处理异常的方法是的好处是比较简单,但是一般我们不会这样做,通过ResponseStatusException会更加方便,可以避免我们额外的异常类。

        @GetMapping("/resourceNotFoundException2")
        public void throwException3() {
            throw new ResponseStatusException(HttpStatus.BAD_GATEWAY,"The resource not found",new ReourceNotFoundException());
        }

    ResponseStatusException 提供了三个构造方法:

        public ResponseStatusException(HttpStatus status) {
            this(status, null, null);
        }
    
        public ResponseStatusException(HttpStatus status, @Nullable String reason) {
            this(status, reason, null);
        }
    
        public ResponseStatusException(HttpStatus status, @Nullable String reason, @Nullable Throwable cause) {
            super(null, cause);
            Assert.notNull(status, "HttpStatus is required");
            this.status = status;
            this.reason = reason;
        }

    构造函数中的参数解释如下:

    • status : http status
    • reason :response 的消息内容
    • cause : 抛出的异常
  • 相关阅读:
    去掉DevExpress gridControl控件表头上的的默认英文字母
    【555】folium 更换底图
    github图片不显示问题解决
    厉害了,自己动手实现 LRU 缓存机制!
    一文搞懂 Netty 的整体流程,还有谁不会?
    PageHelper 分页一直有性能问题?
    left join 后用 on 还是 where,区别大了!
    不推荐别的了,IDEA 自带的数据库工具就很牛逼!
    王炸!!IDEA 2021.1 推出语音、视频功能,边写代码边聊天,我真的服了…
    别再面向 for 循环编程了,Spring 自带的观察者模式就很香!
  • 原文地址:https://www.cnblogs.com/ustc-anmin/p/11731344.html
Copyright © 2011-2022 走看看