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);
	}
}
相关推荐
比花花解语20 分钟前
Java中Integer的缓存池是怎么实现的?
java·开发语言·缓存
JOJO___1 小时前
Spring IoC 配置类 总结
java·后端·spring·java-ee
蜗牛学苑_武汉1 小时前
设计模式之代理模式
java·网络·java-ee·代理模式
极客先躯1 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
luoluoal2 小时前
java项目之企业级工位管理系统源码(springboot)
java·开发语言·spring boot
ch_s_t2 小时前
新峰商城之购物车(一)
java·开发语言
蜜桃小阿雯2 小时前
JAVA开源项目 校园美食分享平台 计算机毕业设计
java·jvm·spring boot·spring cloud·intellij-idea·美食
黄昏_2 小时前
苍穹外卖Day01-2
java·spring
努力的八爪鱼2 小时前
记录工作中遇到的问题(持续更新~)
java
求学小火龙2 小时前
ElasticSearch介绍+使用
java·大数据·elasticsearch