SpringBoot全局异常处理(三十)下

四.二 自定义全局异常处理器 MyExceptionHandler

通过 @ExceptionHandler 注解,接收相应的异常信息

@RestControllerAdvice
public class MyExceptionHandler {
    /**
     * 处理空指向的异常信息
     * @date 2021/11/10 11:52
     * @author zk_yjl
     * @param
     * @return top.yueshushu.learn.response.OutputResult
     */
    @ExceptionHandler(NullPointerException.class)
    public OutputResult npeException(HttpServletRequest req, NullPointerException e){
        return OutputResult.fail(e.getMessage());
    }
    /**
     * 处理算术的异常信息
     * @date 2021/11/10 11:52
     * @author zk_yjl
     * @param
     * @return top.yueshushu.learn.response.OutputResult
     */
    @ExceptionHandler(ArithmeticException.class)
    public OutputResult ariException(HttpServletRequest req, ArithmeticException  e){
        return OutputResult.fail(e.getMessage());
    }
    /**
     * 处理数组下标越界异常的异常信息
     * @date 2021/11/10 11:52
     * @author zk_yjl
     * @param
     * @return top.yueshushu.learn.response.OutputResult
     */
    @ExceptionHandler(ArrayIndexOutOfBoundsException.class)
    public OutputResult arrException(HttpServletRequest req, ArrayIndexOutOfBoundsException  e){
        return OutputResult.fail(e.getMessage());
    }
    /**
     * 处理自定义的业务异常的异常信息
     * @date 2021/11/10 11:52
     * @author zk_yjl
     * @param
     * @return top.yueshushu.learn.response.OutputResult
     */
    @ExceptionHandler(BusinessException.class)
    public OutputResult busException(HttpServletRequest req, BusinessException  e){
        return OutputResult.fail(e.getMessage());
    }
    /**
     * 处理其他的另外异常的异常信息
     * @date 2021/11/10 11:52
     * @author zk_yjl
     * @param
     * @return top.yueshushu.learn.response.OutputResult
     */
    @ExceptionHandler(Exception.class)
    public OutputResult otherException(HttpServletRequest req, Exception  e){
        return OutputResult.fail(e.getMessage());
    }
}


这时候,再进行访问:


SpringBoot全局异常处理(三十)下

SpringBoot全局异常处理(三十)下

SpringBoot全局异常处理(三十)下

SpringBoot全局异常处理(三十)下


目前老蝴蝶的 状态码都是 500, 实际用的时候,会定义成不同的状态码, npe表示 300, 除 o表示 301,其它异常都有各自的状态码。


前端可以根据状态码,进行不同的展示信息


从而实现前后端分离下的全局异常处理机制.


五. 非抛出异常处理

在实际的业务中,会有 dao数据库层,servie层, controller 层,每一层都会有相应的异常抛出,也可以各自在自己的层捕获异常。


当异常被补获时,没有被抛出时,是什么情况呢? 一般不会在 dao层捕获异常.


五.一 Service 层

public interface ExceptionService {
    /**
     普通的两个异常信息,不补获
     */
    public void div();
    /**
     普通的两个异常信息,内部进行补获
     */
    public void tryDiv();
    /**
     往外抛出异常
     */
    public void throwDivExcepiton() throws Exception;
    public void throwBusExcepiton() throws Exception;
}


五.二 SerivceImpl 实现

@Service
public class ExceptionServiceImpl implements ExceptionService {
    @Override
    public void div() {
        int a=10/0;
    }
    @Override
    public void tryDiv() {
        try{
            int a=10/0;
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    @Override
    public void throwDivExcepiton() throws Exception {
        try{
            int a=10/0;
        }catch (Exception e){
            throw e;
        }
    }
    @Override
    public void throwBusExcepiton() throws Exception {
        throw new BusinessException("数据库查询出现异常");
    }
}


五.三 Controller 层 ServiceExceptionController

@RestController
@RequestMapping("/exce")
public class ServiceExceptionController {
    @Autowired
    private ExceptionService exceptionService;
    @GetMapping("/div")
    public OutputResult div(){
        exceptionService.div();
        return OutputResult.success();
    }
    @GetMapping("/tryDiv")
    public OutputResult tryDiv(){
        exceptionService.tryDiv();
        return OutputResult.success();
    }
    @GetMapping("/throwDivExcepiton")
    public OutputResult throwDivExcepiton() throws Exception {
        exceptionService.throwDivExcepiton();
        return OutputResult.success();
    }
    @GetMapping("/throwBusExcepiton")
    public OutputResult throwBusExcepiton() throws Exception {
        exceptionService.throwBusExcepiton();
        return OutputResult.success();
    }
    @GetMapping("/throwDivExcepiton2")
    public OutputResult throwDivExcepiton2() {
      try{
          exceptionService.throwDivExcepiton();
          return OutputResult.success();
      }catch (Exception e){
          e.printStackTrace();
          return OutputResult.success("内部补获异常");
      }
    }
    @GetMapping("/throwBusExcepiton2")
    public OutputResult throwBusExcepiton2() {
        try{
            exceptionService.throwBusExcepiton();
            return OutputResult.success();
        }catch (Exception e){
            e.printStackTrace();
            return OutputResult.success("内部补获异常");
        }
    }
    /*
    * 异常处理,
    * 出现的异常,没有显式的捕获,都会接收到。如果被try  catch 到,即不往外抛出, 抛出到 controller 层的话, 是不会接收到这个异常的。
    * 从而不触发异常机制信息.
    * */
}


运行处理展示:


五.三.一 div 方法

service 层和 controller 层均没有 捕获异常

SpringBoot全局异常处理(三十)下



五.三.二 tryDiv

service 层捕获异常, controller 层没有捕获

SpringBoot全局异常处理(三十)下



没有接收到异常信息


五.三.三 throwDivExcepiton

service 层捕获异常,但往外抛出了, controller 层继续抛出


SpringBoot全局异常处理(三十)下


五.三.四 throwBusExcepiton

service 层抛出异常, controller 层继续抛出


SpringBoot全局异常处理(三十)下


五.三.五 throwDivExcepiton2

service 层捕获异常,但继续抛出异常, controller 捕获异常


SpringBoot全局异常处理(三十)下


五.三.六 throwBusExcepiton2

service 层抛出异常, controller 捕获异常


SpringBoot全局异常处理(三十)下


总结: 异常捕获,是在 Controller 层再往上一层进行处理的, 如果 Controller 层抛出异常,才能获取到,转换成 json的形式,如果 controller 层不抛出异常,是无法获取到的,也无法转换成 json的形式.


上一篇:SpringBoot系统启动任务(三十二)的方式(下)


下一篇:SpringBoot通过Cors解决跨域问题(三十一)上