本文主要介绍自己在工作中在处理抛出异常类和封装响应类处理的模板总结。
对于后端程序员来说,抛出异常和返回响应别提有多重要了对吧。其实在真正的企业级开发中,这步工作也不需要你去做,公司都给你封装好了的,你直接用就行。由于我最近从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}) @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,"服务器端异常"); } }
响应类模板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如下: