《Spring Boot应用进阶:打造优雅的错误处理机制与全局异常拦截器》

server/2024/10/18 18:35:12/

文章目录

    • 自定义异常类AppException
    • 封装业务有关的枚举类AppExceptionCodeMsg
    • 全局异常拦截器Handler
    • 响应类模板Resp
    • 案例展示 || Demo
      • 项目结构
      • pom依赖
      • DemoController
      • 实际执行结果
    • Demo案例Git地址 | Gitee

本文主要介绍自己在工作中在处理抛出异常类和封装响应类处理的模板总结。

对于后端程序员来说,抛出异常和返回响应别提有多重要了对吧。其实在真正的企业级开发中,这步工作也不需要你去做,公司都给你封装好了的,你直接用就行。由于我最近从0到1负责了一个完整的项目,在最近的后期优化过程中,我需要考虑重新设计 自定义异常类与统一响应,所以特此总结该文,以供学习。

自定义异常类AppException

自定义异常类AppException需要继承至 RuntimeException运行时异常。

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

封装业务有关的枚举类AppExceptionCodeMsg

利用枚举类将常用的业务异常进行配置,封装:

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

这样做的好处是,配置灵活,不需要去硬编码。

完整的枚举类如下:

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

全局异常拦截器Handler

这个拦截器的作用就是在抛出异常之前进行拦截,先判断是不是要抛出你自定义的异常,如果不是则放行。

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = {Exception.class})@ResponseBodypublic <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,"服务器端异常");}
}

响应类模板Resp

其实这个响应类模板网上到处都是,自己也可以随意找到,以下是我的模板:

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

案例展示 || Demo

接下来我将用一个SpringBoot项目综合上述异常类与响应类综合展示具体情况,看官们也可以自行下载demo直接在自己的电脑上跑起来学习。

项目结构

│  pom.xml
├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─linghu
│  │  │          └─demo
│  │  │              │  DemoApplication.java
│  │  │              │
│  │  │              ├─controller
│  │  │              │      DemoController.java
│  │  │              │
│  │  │              ├─exception
│  │  │              │      AppException.java
│  │  │              │      AppExceptionCodeMsg.java
│  │  │              │      GlobalExceptionHandler.java
│  │  │              │
│  │  │              └─resp
│  │  │                      Resp.java
│  │  │
│  │  └─resources
│  │          application.yml
│  │
│  └─test
│      └─java

pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>exceptiondemo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-boot.version>2.3.7.RELEASE</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>

DemoController

web层api代码设计如下:

@RestController
public class DemoController {@GetMapping("demo")public Resp<String> demo1(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);}
}

实际执行结果

在这里插入图片描述

大家可以自行下载代码跑一跑学习一下。

Demo案例Git地址 | Gitee

该教程其实很简单,欢迎大家下载学习!

完整Demo如下:
《Exception_Auto_Demo》


http://www.ppmy.cn/server/126471.html

相关文章

golang web笔记-3.响应ResponseWriter

简介 从服务器向客户端返回响应需要使用 ResponseWriter&#xff0c;ResponseWriter是一个接口&#xff0c;handler用它来返回响应。 ResponseWriter常用方法 Write&#xff1a;接收一个byte切片作为参数&#xff0c;然后把它写入到响应的body中。如果Write被调用时&a…

封装了一个iOS水平方向动态宽度layout

我们有时候会遇到这样的情形&#xff0c;就是需要展示一些动态的标签&#xff0c;宽度是动态的&#xff0c; 水平方向是一行&#xff0c;其实这种情况还是比较容易处理的&#xff0c;只是一下子想不起来&#xff0c; 这里做了一个相关的需求&#xff0c;将思路和代码记录下来&a…

第 21 章 一条记录的多幅面孔——事务的隔离级别与 MVCC

21.1 事前准备 CREATE TABLE hero ( number INT, NAME VARCHAR ( 100 ), country VARCHAR ( 100 ), PRIMARY KEY ( number ) ) ENGINE INNODB CHARSET utf8;INSERT INTO hero VALUES ( 1, 刘备, 蜀 );21.2 事务隔离级别 在保证事务隔离性的前提下&#xff0c;使用不同的隔…

5G NR 协议规范表(对应3GPP 协议编号)

文章目录 5G NR 协议规范表&#xff08;对应3GPP 协议编号&#xff09;5G 架构相关协议5G 新空口相关协议无线接入网相关协议终端相关协议 5G NR 协议规范表&#xff08;对应3GPP 协议编号&#xff09; 5G 架构相关协议 5G 新空口相关协议 无线接入网相关协议 终端相关协议

Web3.0 应用项目

Web3.0 是下一代互联网的概念&#xff0c;旨在去中心化、用户拥有数据控制权和通过区块链技术实现信任的网络。Web3.0的应用项目主要集中在区块链、加密货币、去中心化应用 (DApps)、去中心化金融 (DeFi)、NFT&#xff08;非同质化代币&#xff09;等领域。以下是一些典型的 We…

Log4j的配置与使用详解

Log4j的配置与使用详解 Log4j介绍 Log4j是Apache的一个开源项目&#xff0c;通过使用Log4j&#xff0c;我们可以控制日志信息输送的目的地是控制台、文件、GUI组件&#xff0c;我们可以控制每条日志的输出格式&#xff1b;只需要通过一个配置文件就可以灵活的配置&#xff0c…

软件测试|数据库常见面试题

在软件测试数据库的面试中&#xff0c;面试官通常会考察应聘者对数据库的理解、SQL语言的应用、数据库性能优化、以及数据库相关的技术栈和工具等方面的知识。以下是一些可能的面试问题及建议的回答思路&#xff1a; 1、什么是关系型数据库&#xff0c;主键&#xff0c;外键&am…

web笔记

<form method"POST" action"{{ url_for(register) }}"><label for"username">用户名:</label><input type"text" id"username" name"username" required><br><label for"p…