前言

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

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

1、@ExceptionHandler注解标注的方法:用于捕获Controller中抛出的不同类型的异常,从而达到异常全局处理的目的;
2、@ModelAttribute注解标注的方法:表示此方法会在执行目标Controller方法之前执行;
3、@InitBinder注解标注的方法:用于请求中注册自定义参数的解析,从而达到自定义请求参数格式的目的;

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

1、工程包结构

在这里插入图片描述

2、POM依赖

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

3、Java代码

AppExceptionCodeMsg

//这个枚举类中定义的都是跟业务有关的异常
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

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

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

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

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);
	}
}

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部