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

文章目录

    • 前言
    • 1、工程包结构
    • 2、POM依赖
    • 3、Java代码

前言

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/879175.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++篇】C++类与对象深度解析(三):类的默认成员函数详解

文章目录 【C篇】C类与对象深度解析&#xff08;三&#xff09;前言4. 运算符重载基本概念4.1 运算符重载的基本概念4.2 重载运算符的规则4.3 成员函数重载运算符4.4 运算符重载的优先级与结合性4.5 运算符重载中的限制与特殊情况4.5.1 不能创建新的操作符4.5.2 无法重载的运算…

uniapp离线(本地)打包

安卓离线打包 注意&#xff1a;jdk建议选择1.8 下载Android Studio配置gradle仓库地址 第一步&#xff1a;先下载对应的版本&#xff0c;进行压缩包解压 第二步&#xff1a;在电脑磁盘&#xff08;D盘&#xff09;&#xff0c;创建文件夹存放压缩包并进行解压&#xff0c;并创…

python-简单的数据结构

题目描述 小理有一天在网上冲浪的时候发现了一道很有意思的数据结构题。 该数据结构形如长条形。 一开始该容器为空&#xff0c;有以下七种操作。 1 a从前面插入元素 a ; 2 从前面删除一个元素; 3 a从后面插入一个元素; 4 从后面删除一个元素; 5 将整个容器头尾翻转; 6 输出个…

阻止冒泡事件

每一div都有一个切换事件 div里包括【复制】事件&#xff0c; 点击【复制按钮】&#xff0c;会触发【切换事件】 因为冒泡 在 Vue 3 中&#xff0c;阻止 click 事件冒泡可以使用以下常规方法&#xff1a; 1 事件修饰符&#xff1a;Vue 3 中提供了多种事件修饰符&#xff0c…

buildroot移植qt报错Info: creating stash file (补充qt添加字库)

移植qt库&#xff0c;编译文件报错Info: creating stash file /home/rbing/QT/uart/.qmake.stash Project ERROR: Unknown module(s) in QT: serialport rbingouc:~/QT/uart$ /home/rbing/linux/tool/buildroot-2022.02.9/output/host/usr/bin/qmake Info: creating stash fil…

【LeetCode】每日一题 2024_9_18 坐上公交的最晚时间(排序,模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;坐上公交的最晚时间 代码与解题思路 func latestTimeCatchTheBus(buses []int, passengers []int, capacity int) (ans int) {// 核心思路分析&#xff1a;// 你可以搭乘公交车的最晚到达…

【数据仓库】数据仓库常见的数据模型——维度模型

文章部分图参考自&#xff1a;多维数据模型各种类型&#xff08;星型、雪花、星座、交叉连接&#xff09; - 知乎 (zhihu.com) 文章部分文字canla一篇文章搞懂数据仓库&#xff1a;四种常见数据模型&#xff08;维度模型、范式模型等&#xff09;-腾讯云开发者社区-腾讯云 (ten…

React18快速入门

需要先安装并配置React相关的工具和插件 下载安装Node.js&#xff0c;这里以MacOS Node.js v22.6.0为例 终端命令行检查是否安装成功 node -v npm -vNode.js快速入门 npm设置镜像源 #设置为阿里镜像源 npm config set registry https://registry.npmmirror.com #查看是否生…

初始Linux 和 各种常见指令

目录 Linux背景 1. 发展史 Linux发展历史 1.历史 2. 开源 Linux下基本指令 01. ls 指令 02. pwd命令 03. cd 指令 04. touch指令 05.mkdir指令&#xff08;重要&#xff09;&#xff1a; 06.rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a; …

Minio环境搭建(单机安装包、docker)(一)

前言&#xff1a; 项目中客户不愿意掏钱买oss&#xff0c;无奈只能给他免费大保健来一套。本篇文章只是记录验证可行性&#xff0c;毕竟minio太少文档了&#xff0c;参考着官网来。后面还会再出一套验证集群部署的文章。 一、资料 MinIO官网&#xff1a; MinIO | S3 Compatib…

web渗透—RCE

一&#xff1a;代码执行 相关函数 1、eval()函数 assert()函数 (1)原理&#xff1a;将用户提交或者传递的字符串当作php代码执行 (2)passby:单引号绕过&#xff1a;闭合注释&#xff1b;开启GPC的话就无法绕过&#xff08;GPC就是将单引号转换为"反斜杠单引号"&a…

基于python+django+vue的鲜花商城系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的线…

[数据集][目标检测]俯拍航拍森林火灾检测数据集VOC+YOLO格式6116张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6116 标注数量(xml文件个数)&#xff1a;6116 标注数量(txt文件个数)&#xff1a;6116 标注…

图像滤波---各项异性扩散滤波使用笔记及代码

图像滤波---各项异性扩散滤波使用笔记及代码 一、文章内容介绍二、各项异性扩散滤波和各项同性滤波1、各项同性滤波2、各项异性扩散滤波3、各项异性和各项同性的对比 三、各项异性扩散滤波的原理介绍四、各项异性扩散滤波公式五、公式中的参数使用说明1、扩散速率 λ \lambda λ…

【C++】虚函数

一、什么是虚函数 在类的成员函数前加上virtual关键字&#xff0c;这个函数就是虚函数。 虚函数的所用就是完成多态。多态示例如下&#xff1a; class A {public:virtual void func()//虚函数{cout << "A" << endl;}void ftwo()//普通函数{cout <&…

黑神话·悟空藕丝步云履怎么获得?来看这一篇

1、传送到花果山-山脚-青嶂道土地庙。 2、在这里召唤筋斗云飞行岛章节刚开始的的初始位置方向 在这里推荐一款旗舰开放式耳机南卡OE Pro2&#xff0c;在目前有许多开放式耳机产品存在佩戴舒适度低且音质表现非常一般的当下&#xff0c;南卡开放式耳机凭借“非常规”的软硬结合…

Vue2电商平台项目 (三) Search模块、面包屑(页面自己跳自己)、排序、分页器!

文章目录 一、Search模块1、Search模块的api2、Vuex保存数据3、组件获取vuex数据并渲染(1)、分析请求数据的数据结构(2)、getters简化数据、渲染页面 4、Search模块根据不同的参数获取数据(1)、 派发actions的操作封装为函数(2)、设置带给服务器的参数(3)、Object.assign整理参…

智慧宿舍平台|基于Springboot+vue的智慧宿舍系统(源码+数据库+文档)

智慧宿舍系统 目录 基于Springbootvue的智慧宿舍系统 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#xff0c;阿里云开发社区乘风者…

java多线程模拟多个售票员从同一个票池售票

程序功能 这段代码模拟了多个售票员从一个有限的票池中售票的过程。主要功能如下&#xff1a; 票池共有50张票&#xff0c;多个售票员&#xff08;线程&#xff09;并发进行售票。 使用同步机制确保线程安全&#xff0c;避免多个售票员同时出售同一张票。 每个售票员不断检查票…

51单片机 - DS18B20实验1-读取温度

上来一张图&#xff0c;明确思路&#xff0c;程序整体裤架如下&#xff0c;通过单总线&#xff0c;单独封装一个.c文件用于单总线的操作&#xff0c;其实&#xff0c;我们可以把点c文件看成一个类操作&#xff0c;其属性就是我们面向对象的函数&#xff0c;也叫方法&#xff0c…