SSM项目 异常处理器,如何处理异常?

引言

项目跑起来后,可能出现的异常如下:

可以看到,异常无处不在,种类繁多,那么我们应该如何处理异常呢?如果在每个可能出现异常的方法中书写处理异常的代码,代码量大且容易出错。

解决:我们可以把异常都抛出,所有抛出的异常集中到控制层统一处理,Spring基于AOP的实现思想为我们提供了这样一个异常处理器。

异常处理器的使用

两个注解

在controller层中定义异常控制器

//确保SpringMVC的配置类能扫到它
//异常处理器
@RestControllerAdvice//REST风格的异常处理器
public class ProjectExceptionAdvice {
    //用@ExceptionHandler注解选择要处理的异常类型
    @ExceptionHandler(ArithmeticException.class)
    public Result handlerException01(ArithmeticException e){
        return new Result(Code.ARITHMETIC_EXP,"出现算术异常",null);
    }

}

测试

查询所有业务(1/0为故意添加的算术异常)

    @Override
    public List<Book> selectAllBooksService() {
        System.out.println("deal with selectAllBooksService...");
        int a=1/0;
        List<Book> books = bookMapper.selectAllBooks();
        return books;
    }

 测试结果

 **************************************************************************************************************

项目异常处理方案

有了异常处理器后,我们可以捕获异常,但是异常种类繁多,如果对每一种异常都定义方法来处理,那要写的方法也太多了。因此可以把异常分为如下三大类

三大异常

业务异常

系统异常

其他异常

 解决方案

简单点说,作为开发人员

对于业务异常(BusinessException),是我们编写程序时已经预计到的,处理时要根据异常的Code进行分类处理。

对于系统异常(SystemException),是我们可以预料到的,但是我们无法解决,处理时需要联系运维人员并记录日志,安抚用户。

对于其他异常(Exception),是我们没有预料到的,是我们项目设计的漏洞,处理时要安抚用户,记录日志,然后再去解决。

案例

异常类别码

    public static final Integer BUSINESS_EXP=50000;
    public static final Integer BUSINESS_ARITHMETIC_EXP=500010; //业务异常里面的算术异常

    public static final Integer SYSTEM_EXP=51000;

    public static final Integer UNKNOWN_EXP=52000;

自定义异常

业务异常
public class BusinessException extends RuntimeException{
    private Integer code;//异常细分码

    public BusinessException() {
        this.code= Code.BUSINESS_EXP;
    }

    public BusinessException(Integer code,String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(String message, Throwable cause, Integer code) {
        super(message, cause);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}
系统异常
public class SystemExption extends RuntimeException{
    private Integer code;

    public SystemExption() {
        this.code= Code.SYSTEM_EXP;
    }

    public SystemExption(Integer code,String message) {
        super(message);
        this.code = code;
    }

    public SystemExption(String message, Throwable cause, Integer code) {
        super(message, cause);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}

异常处理器 

//确保SpringMVC的配置类能扫到它
//异常处理器
@RestControllerAdvice//REST风格的异常处理器
public class ProjectExceptionAdvice {

    @ExceptionHandler
    //处理业务异常
    public Result handleBusinessException(BusinessException e){
        return new Result(e.getCode(),e.getMessage(),null);
    }

    @ExceptionHandler
    //处理系统异常
    public Result handleSystemException(SystemExption e){
        /*
            记录日志
            发送消息给运维....
         */
        return new Result(e.getCode(),e.getMessage(),null);
    }

    @ExceptionHandler
    public Result handleException(Exception e){
        //未预料到的异常,安抚用户
        return new Result(Code.UNKNOWN_EXP,e.getMessage(),"系统升级中,稍安勿躁");
    }

}

可能出现异常的代码用try catch包裹,在所有业务方法头(顶层调用者)抛出Exception,我们系统的漏洞会被异常处理器中的handleException方法拦截。

---------------------------------------------------------------------------------------------------------------------

情况1

    @Override
    public List<Book> selectAllBooksService() throws RuntimeException{
        System.out.println("deal with selectAllBooksService...");
        //可能出现业务异常的代码用try catch包裹
        try{
            int a=1/0;
        }catch (Exception e){
            throw new BusinessException(Code.BUSINESS_ARITHMETIC_EXP,"不要再表演1除0了");
        }

        List<Book> books = bookMapper.selectAllBooks();
        return books;
    }

业务异常,抛出异常信息,规范用户行为 。

情况2

    @GetMapping
    public Result selectAllBooks() throws Exception{
        List<Book> books = bookService.selectAllBooksService();
        return new Result(books==null?Code.SELECT_OK:Code.SELECT_ERR,"查询所有",books);
    }

selectAllBooks时selectAllBooksService的顶层调用者 ,让他抛出Exception

    @Override
    public List<Book> selectAllBooksService(){
        System.out.println("deal with selectAllBooksService...");
        int [] b={1,2};
        b[3]=666;//这是我们没有预料到的异常
        //可能出现业务异常的代码用try catch包裹
        try{
            int a=1/0;
        }catch (Exception e){
            throw new BusinessException(Code.BUSINESS_ARITHMETIC_EXP,"不要再表演1除0了");
        }

        List<Book> books = bookMapper.selectAllBooks();
        return books;
    }

出现了我们没有预料到的异常,先安抚用户,再去看日志解决问题。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值