springboot(十三)全局异常处理

x33g5p2x  于2021-12-17 转载在 其他  
字(3.1k)|赞(0)|评价(0)|浏览(359)

前言:

      不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。所以我们需要一个全局异常类。自定义我们的异常信息。

实现:

新建项目:springboot-exception,pom.xml

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>
    </dependencies>

自定义提示码类:CodeMsg.java

@Data
public class CodeMsg {
	private int code;
	private String msg;
	//错码定义误
	public static CodeMsg SUCCESS = new CodeMsg(0, "success");
	public static CodeMsg SERVER_ERROR = new CodeMsg(50000, "服务端异常");
	public static CodeMsg BIND_ERROR = new CodeMsg(50001, "参数校验异常:%s");
	public static CodeMsg REQUEST_ILLEGAL = new CodeMsg(50002, "请求非法");
	
	private CodeMsg( int code,String msg ) {
		this.code = code;
		this.msg = msg;
	}
	
	public CodeMsg fillArgs(Object... args) {
		int code = this.code;
		String message = String.format(this.msg, args);
		return new CodeMsg(code, message);
	}
	
}

自定义返回格式类:Result.java

@Data
public class Result<T> {
	//提示码
	private int code;
	//消息
	private String msg;
	//返回提示
	private T data;
	
	/**
	 *  成功时候的调用
	 * */
	public static  <T> Result<T> success(T data){
		return new Result<T>(data);
	}
	
	/**
	 *  失败时候的调用
	 * */
	public static  <T> Result<T> error(CodeMsg codeMsg){
		return new Result<T>(codeMsg);
	}
	
	private Result(T data) {
		this.data = data;
	}
	
	private Result(int code, String msg) {
		this.code = code;
		this.msg = msg;
	}
	
	private Result(CodeMsg codeMsg) {
		if(codeMsg != null) {
			this.code = codeMsg.getCode();
			this.msg = codeMsg.getMsg();
		}
	}

}

自定义异常类:GlobalException.java。你可以自定义普通的Exception,也可以自定义RuntimeException

public class GlobalException extends RuntimeException{

	private static final long serialVersionUID = 1L;
	
	private CodeMsg cm;
	
	public GlobalException(CodeMsg cm) {
		super(cm.toString());
		this.cm = cm;
	}

	public CodeMsg getCm() {
		return cm;
	}

}

统一异常处理类:GlobalExceptionHandler.java

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    @ExceptionHandler(value = Exception.class)
    public Result exceptionHandler(HttpServletRequest request, Exception e) {
        e.printStackTrace();
        //判断是否为自定义异常 
        if (e instanceof GlobalException) {
            GlobalException ex = (GlobalException) e;
            return Result.error(ex.getCm());
        } else if (e instanceof BindException) {
            BindException ex = (BindException) e;
            List<ObjectError> errors = ex.getAllErrors();
            ObjectError error = errors.get(0);
            String msg = error.getDefaultMessage();
            return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg));
        } else {
            return Result.error(CodeMsg.SERVER_ERROR);
        }
    }
}

     注:@ControllerAdvice 注解定义全局异常处理类
              @ExceptionHandler 指定自定义错误处理方法拦截的异常类型

            在if判断中我们可以自己定义需要捕获的异常种类,你可以自定定义多个异常类在这里来抛出

测试接口:TestCotroller.java

@RestController
public class TestController {
    @GetMapping("/index")
    public Result index(String name) {
        if(StringUtils.isEmpty(name)){
            //抛出自定义异常 CodeMsg为自定义的异常码
            throw new GlobalException(CodeMsg.BIND_ERROR.fillArgs(name));
        }
        return Result.success(name);
    }

}

源码地址: https://gitee.com/xu0123/springboot2

相关文章