SpringBoot2:web开发常用功能实现及原理解析-@ControllerAdvice实现全局异常统一处理

文章目录

前言

本篇主要针对前后端分离的项目,做的一个统一响应包装、统一异常捕获处理。

Spring里,我们可以使用@ControllerAdvice来声明一些关于controller的全局性的东西,其用法主要有以下三点:

1、@ExceptionHandler注解标注的方法:用于捕获Controller中抛出的不同类型的异常,从而达到异常全局处理的目的;

2、@ModelAttribute注解标注的方法:表示此方法会在执行目标Controller方法之前执行;

3、@InitBinder注解标注的方法:用于请求中注册自定义参数的解析,从而达到自定义请求参数格式的目的;

参考:
@ControllerAdvice注解作用及源码解析
@ControllerAdvice 的介绍及三种用法

1、工程包结构

2、POM依赖

xml 复制代码
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

3、Java代码

AppExceptionCodeMsg

java 复制代码
//这个枚举类中定义的都是跟业务有关的异常
public enum AppExceptionCodeMsg {

	INVALID_CODE(10000,"验证码无效"),
	USERNAME_NOT_EXISTS(10001,"用户名不存在"),
	USER_CREDIT_NOT_ENOUTH(10002,"用户积分不足");
	;

	private int code ;
	private String msg ;

	public int getCode() {
		return code;
	}

	public String getMsg() {
		return msg;
	}


	AppExceptionCodeMsg(int code, String msg){
		this.code = code;
		this.msg = msg;
	}

}

AppException

java 复制代码
public class AppException extends RuntimeException{

	private int code = 500;
	private String msg = "服务器异常";


	public AppException(AppExceptionCodeMsg appExceptionCodeMsg){
		super();
		this.code = appExceptionCodeMsg.getCode();
		this.msg = appExceptionCodeMsg.getMsg();

	}

	public AppException(int code,String msg){
		super();
		this.code = code;
		this.msg = msg;

	}

	public int getCode() {
		return code;
	}

	public String getMsg() {
		return msg;
	}

}

Resp

java 复制代码
import com.atguigu.boot.exception.AppExceptionCodeMsg;

public class Resp<T> {

	//服务端返回的错误码
	private int code = 200;
	//服务端返回的错误信息
	private String msg = "success";
	//我们服务端返回的数据
	private T data;

	private Resp(int code,String msg,T data){
		this.code = code;
		this.msg = msg;
		this.data = data;
	}

	public static <T> Resp success(T data){
		Resp resp = new Resp(200, "success", data);
		return resp;
	}

	public static <T> Resp success(String msg,T data){
		Resp resp = new Resp(200,msg, data);
		return resp;
	}

	public static <T> Resp error(AppExceptionCodeMsg appExceptionCodeMsg){
		Resp resp = new Resp(appExceptionCodeMsg.getCode(), appExceptionCodeMsg.getMsg(), null);
		return resp;
	}
	public static <T> Resp error(int code,String msg){
		Resp resp = new Resp(code,msg, null);
		return resp;
	}

	public int getCode() {
		return code;
	}

	public String getMsg() {
		return msg;
	}

	public T getData() {
		return data;
	}

}

GlobalExceptionHandler

java 复制代码
import com.atguigu.boot.bean.Resp;
import com.atguigu.boot.exception.AppException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class GlobalExceptionHandler {


	@ExceptionHandler(value = {Exception.class})
	@ResponseBody
	public <T> Resp<T> exceptionHandler(Exception e){
		//这里先判断拦截到的Exception是不是我们自定义的异常类型
		if(e instanceof AppException){
			AppException appException = (AppException)e;
			return Resp.error(appException.getCode(),appException.getMsg());
		}

		//如果拦截的异常不是我们自定义的异常(例如:数据库主键冲突)
		return Resp.error(500,"服务器端异常");
	}
}

ExpTestController

java 复制代码
import com.atguigu.boot.bean.Resp;
import com.atguigu.boot.exception.AppException;
import com.atguigu.boot.exception.AppExceptionCodeMsg;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

@RestController
public class ExpTestController {

	@GetMapping("demo")
	public Resp<String> demo(String name){

		if("ok".equals(name)){
			return Resp.success("succ");
		}
		if("err".equals(name)){
			//抛业务相关的异常
			throw new AppException(AppExceptionCodeMsg.USERNAME_NOT_EXISTS);
		}

		if("errcode".equals(name)){
			throw new AppException(AppExceptionCodeMsg.INVALID_CODE);
		}
		if("0".equals(name)){
			int i=1/0;
		}

		//检查用户积分是否足够,如果不够,就抛出异常
		if("notenough".equals(name)){
			throw new AppException(AppExceptionCodeMsg.USER_CREDIT_NOT_ENOUTH);
		}

		return Resp.success("default");
	}

	@GetMapping("list")
	public Resp<List> list(){
		List<String> list = Arrays.asList("zhangsan","lisi","wangwu");

		return Resp.success(list);
	}
}
相关推荐
suweijie7683 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿4 小时前
List深拷贝后,数据还是被串改
java
xlsw_7 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹7 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭8 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫8 小时前
泛型(2)
java
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
南宫生8 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石8 小时前
12/21java基础
java
李小白669 小时前
Spring MVC(上)
java·spring·mvc