java统一异常处理

我之前做过一个项目,采用的是前端和后端分离,某些时候后台出现了异常,直接给前端抛了一个500错误,这种错误会被用户看到非常不友好,于是就有了以下统一异常处理,就是把所有的异常都经过处理,按照前端可读的格式返回。

一、对比返回结果如下

1.没有做统一异常处理前,后台出现异常返回结果如下图

2.做了统一异常处理,后台出现异常返回的结果如下图

 

 总结:1.没有对出现的异常做处理,让默认抛出500错误,前端处理麻烦、且对用户不友好

            2.对出现的异常做了统一的格式处理,并封装成固定格式、前端处理简单、提示消息友好

 

二、具体实现步骤

1.之前处理工程异常,代码中最常见的就是try-catch-finally,有时一个try,多个catch,覆盖了核心业务逻辑,现在使用

Spring能够较好的处理这种问题,核心如下,文章主要关注前两个:

  • @ExceptionHandler:统一处理某一类异常,从而能够减少代码重复率和复杂度
  • @ControllerAdvice:异常集中处理,更好的使业务逻辑与异常处理剥离开

demo代码如下

/**
 * @Auther: mzl
 * @Date: 2019/4/11 10:24
 * @Description:
 */
@ControllerAdvice
@RestController
public class CommonExceptionHandler {


    /**
     * Java一般异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String  exceptionHandler(Exception e){
        e.printStackTrace();
        if(e instanceof BindException){
            int index = e.getMessage().lastIndexOf("[");
            return Result.defeatedResultByCodeAndMsg(2, index!= -1?e.getMessage().substring(index + 1,e.getMessage().length()-1).trim():e.getMessage());
        }
        return Result.defeatedResultByMsg(e.toString());
    }

    /**
     * 拦截自定义异常
     * @param ex
     * @return
     */
    @ExceptionHandler(BaseException.class)
    @ResponseBody
    public String exceptionHandler(BaseException ex){
        ex.printStackTrace();
        if(ex.getCode()==null){
            ex.setCode(4);
        }
        return Result.defeatedResultByCodeAndMsg(ex.getCode(),ex.getMsg());
    }
}

 

2.自定义一个异常

/**
 * @Auther: mzl
 * @Date: 2019/4/10 18:02
 * @Description: 异常处理
 */
public class BaseException extends RuntimeException{

    private Integer code;

    private String msg;

    /**
     * 默认异常,状态码为2
     * @param msg
     */
    public BaseException(String msg){
        super();
        this.msg=msg;
        this.code=2;
    }


    /**
     * 自定义异常
     * @param code
     * @param massge
     */
    public BaseException(Integer code,String massge){
        super(massge);
        this.msg=msg;
        this.code=code;
    }


    public BaseException(){
        super("系统错误,请联系管理员");
        this.code=4;
        this.msg="系统错误,请联系管理员";
    }





    public Integer getCode() {
        return code;
    }

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

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

 

 

3.返回结果封装

public class Result {


    private static volatile Consequence consequence=new Consequence();

    /**
     * code结果状态码 0:操作成功;
     */
    public static int code0=0;
    public static int code1=1;//1:未登录;
    public static int code2=2;//2:参数错误;
    public static int code3=3;//3:没有权限;
    public static int code4=4;//4:系统异常
    //时间格式
    public static String dateFormat="yyyy-MM-dd  HH:mm:ss";



    public static String succeedResultByMsgAndDate( String msg, Object date){
        consequence.clear();
        consequence.setCode(code0);
        consequence.setMsg(msg);
        consequence.setDate(date);
        return getResult(consequence);    }

    public static String succeedResultByMsg( String msg){
        consequence.clear();
        consequence.setCode(code0);
        consequence.setMsg(msg);
        consequence.setDate("");
        return getResult(consequence);    }


    public static String succeedResult(){
        consequence.clear();
        consequence.setCode(code0);
        consequence.setMsg("操作成功");
        consequence.setDate("");
        return getResult(consequence);    }


    public static String defeatedResultByMsg(String msg){
        consequence.clear();
        consequence.setCode(code4);
        consequence.setDate("");
        consequence.setMsg("系统异常,请联系管理员");
        consequence.setDevMsg(msg);
        return getResult(consequence);    }

    public static String defeatedResult(){
        consequence.clear();
        consequence.setCode(code4);
        consequence.setDate("");
        consequence.setMsg("系统异常,请联系管理员");
        return getResult(consequence);    }

    public static String noLoginResult(){
        consequence.clear();
        consequence.setCode(code1);
        consequence.setDate("");
        consequence.setMsg("没有登录,请登录");
        return getResult(consequence);    }

    public static String noAuthorityResult(){
        consequence.clear();
        consequence.setCode(code3);
        consequence.setDate("");
        consequence.setMsg("没有权限,请联系管理员分配权限");
        return getResult(consequence);    }

    public static String noAuthorityResultByMsg(String msg){
        consequence.clear();
        consequence.setCode(code3);
        consequence.setDate("");
        consequence.setMsg(msg);
        return getResult(consequence);    }

    public static String errorParameterResult(String 参数错误){
        consequence.clear();
        consequence.setCode(code2);
        consequence.setDate("");
        consequence.setMsg("参数错误,或参数不能为空");
        return getResult(consequence);    }


    public static String errorParameterResultByMsg(String msg){
        consequence.clear();
        consequence.setCode(code2);
        consequence.setDate("");
        consequence.setMsg(msg);
        return getResult(consequence);    }

    public static String defeatedResultByCodeAndMsg(Integer code,String msg){
        consequence.clear();
        consequence.setCode(code);
        consequence.setDate("");
        consequence.setMsg(msg);
        return getResult(consequence);    }



    public static String setResultByCodeAndMsgAndDate(Integer code,String msg, Object date){
        consequence.clear();
        consequence.setCode(code);
        consequence.setDate(date);
        consequence.setMsg(msg);
        return getResult(consequence);
    }


    public static String getResult(Consequence consequence){
        return JSON.toJSONStringWithDateFormat(consequence,dateFormat,SerializerFeature.DisableCircularReferenceDetect);
    }


}




/**
 * @Auther: mzl
 * @Date: 2019/4/11 13:56
 * @Description:结果返回封装工具
 */
public class Consequence {

    private Integer code;

    private String msg;

    private Object date;

    private String devMsg;

    public Integer getCode() {
        return code;
    }

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

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getDate() {
        return date;
    }

    public void setDate(Object date) {
        this.date = date;
    }

    public String getDevMsg() {
        return devMsg;
    }

    public void setDevMsg(String devMsg) {
        this.devMsg = devMsg;
    }

    public void clear(){
        this.code=null;
        this.date=null;
        this.msg=null;
        this.devMsg=null;
    }
}

到此关键代码基本完成,DEMO比较简陋,仅供参考

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值