当前位置:   article > 正文

Springboot 项目当中 自定义异常_springboot 自定义异常

springboot 自定义异常

1、引出问题

在 Java EE 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都难以避免遇到各种异常需要处理的问题。若不对异常进行处理的话,给用户看到异常信息是不好的,对不懂程序的用户来说还以为你的网站出问题了;对懂程序的人来说,看到你的异常信息,会显得很 low,特别是 SQL 出错,甚至还会暴露你的数据库字段。

2、如何解决

  • 手动 try
    • 弊端是到处是重复代码,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。
  • 利用 Spring MVC 的方式
    • Spring MVC 为 Controller 处理方法执行出现异常提供了全局统一处理,可以使用 @ExceptionHandler 配合 @ControllerAdvice 注解实现异常处理,可减少代码量,提高拓展性和可维护性。
    • 添加处理控制器异常处理类,确保 Spring 配置中要能扫描到这个类。
    • 针对不同异常进行不同处理,针对不同处理方法响应的内容,需要进行不同处理,比如原来方法响应 HTML 依然响应 HTML,若原来方法响应 JSON 依然响应 JSON。

3、自定义异常

在开发中还可以根据自己业务的异常情况来自定义业务逻辑异常类,一般继承于 java.lang.RuntimeException。

比如虽然登录出错,也响应 JSON 数据,但其需要提示的消息更详细,所以通过自定义异常,再利用 Spring MVC 全局处理异常方式,针对这个异常进行专门处理。

4、来看代码

1.0 定义一个自定义异常类 继承 java.lang.RuntimeException

package com.itzhouwei.exception;

/****
 * 自定义异常类
 */
public class BusinessException extends RuntimeException{

    private BusinessExceptionCode code;

    public BusinessException (BusinessExceptionCode code) {
        super(code.getDesc());
        this.code = code;
    }

    public BusinessExceptionCode getCode() {
        return code;
    }

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

    /**
     * 不写入堆栈信息,提高性能
     */
    @Override
    public Throwable fillInStackTrace() {
        return this;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

2.0 定义一个异常枚举类

package com.itzhouwei.exception;

public enum BusinessExceptionCode {

    USER_LOGIN_NAME_EXIST("用户名已存在"),
    LOGIN_USER_ERROR("用户名不存在或密码错误"),
    NOT_PERMISSION("没有权限")
            ;

    private String desc;

    BusinessExceptionCode(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

第三步在控制层写一个类 统一异常处理、数据预处理等

package com.itzhouwei.web.advice;


import com.alibaba.fastjson.JSON;
import com.itzhouwei.exception.BusinessException;
import com.itzhouwei.qo.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletResponse;

/**
 * 统一异常处理、数据预处理等
 */
@ControllerAdvice
public class ControllerExceptionHandler {

    private static final Logger LOG = LoggerFactory.getLogger(ControllerExceptionHandler.class);

    /**
     * 校验异常统一处理
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public JsonResult validExceptionHandler(BindException e) {
        JsonResult commonResp = new JsonResult();
        LOG.warn("参数校验失败:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        commonResp.setSuccess(false);
        commonResp.setMsg(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        return commonResp;
    }


//    @ExceptionHandler(value = BusinessException.class)
//    @ResponseBody
//    public JsonResult validExceptionHandler(BusinessException e) {
//        JsonResult commonResp = new JsonResult();
//        LOG.warn("业务异常:{}", e.getCode().getDesc());
//        commonResp.setSuccess(false);
//        commonResp.setMsg(e.getCode().getDesc());
//        return commonResp;
//    }

    /**
     * 校验异常统一处理
     * @param e
     * @return
     *
     * 这里不需要自己去拼接json 所以我导入Fastjson jar包 进行处理
     */
    @ExceptionHandler(BusinessException.class)
    public String exceptionHandler(BusinessException e, HandlerMethod method, Model model, HttpServletResponse response) throws Exception{
        e.printStackTrace(); // 方便开发的时候找 bug
        // 若原本控制器的方法是返回 JSON,现在出异常也应该返回 JSON
        // 获取当前出现异常的方法,判断是否有 ResponseBody 注解,有就代表需要返回 JSON
        LOG.warn("业务异常:{}", e.getCode().getDesc());
        if(method.hasMethodAnnotation(ResponseBody.class)){
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter()
                    .print(JSON.toJSONString(new JsonResult(false,e.getCode().getDesc() )));
            return null;
        }
        model.addAttribute("errorMsg", e.getCode().getDesc());
        // 若原本控制器的方法是返回 HTML,现在也应该返回 HTML
        return "common/error";
    }

    /**
     * 校验异常统一处理
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public JsonResult validExceptionHandler(Exception e) {
        JsonResult commonResp = new JsonResult();
        LOG.error("系统异常:", e);
        commonResp.setSuccess(false);
        commonResp.setMsg("系统出现异常,请联系管理员");
        return commonResp;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/二进制舞者/article/detail/62636
推荐阅读
相关标签
  

闽ICP备14008679号