springboot全局异常处理
gitee地址:springboot全局异常处理
1.目录结构
2.maven依赖
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.1.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<!-- 配置 log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.7.RELEASE</version>
<configuration>
<mainClass>com.qq.ExceptionApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
3.配置文件application.yaml
server:
port: 8080
logging:
level:
com.qq: debug
file: logs/exception.log
4.响应结构
4.1 响应状态码枚举类
/**
* ResultCodeEnum
*
* @blame Android Team
*/
public enum ResultCode {
SUCCESS(200, "操作成功"),
ERROR(500, "操作失败"),
BIZ_ERROR(1000, "通用业务异常"),
FILE_OUT_MAX(9000, "文件超出最大限制"),
FILE_FORMAT_ERROR(9001, "文件格式不正确"),
PARAM_ERROR(9050, "参数错误"),
JSON_FORMAT_ERROR(9051, "Json解析异常"),
SQL_ERROR(9052, "Sql解析异常"),
NETWORK_TIMEOUT(9510, "网络超时"),
UNKNOWN_INTERFACE(9520, "未知的接口"),
REQ_MODE_NOT_SUPPORTED(9530, "请求方式不支持"),
SYS_ERROR(9999, "系统异常");
/**
* 状态码
*/
private final int code;
/**
* 状态信息
*/
private final String msg;
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
ResultCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
}
4.2 统一响应结构
import lombok.Data;
import java.io.Serializable;
/**
* @author 黔程似景
* @description 响应结果封装
* @date 2022/8/21 14:45
* @blame 黔程似景
**/
@Data
public class ResponseResult<T> implements Serializable {
private static final long serialVersionUID = 1175720458347412087L;
/**
* 状态码
*/
private int code;
/**
* 响应信息
*/
private String msg;
/**
* 相关数据
*/
private T data;
/**
* 无参响应成功
*/
public static <T> ResponseResult<T> success() {
return new ResponseResult<T>();
}
/**
* 成功,默认状态码,返回消息,自定义返回数据
*
* @param data 自定义返回数据
* @param <T> 返回类泛型,不能为String
* @return 通用返回Result
*/
public static <T> ResponseResult<T> success(T data) {
return new ResponseResult<T>(data);
}
/**
* 成功,默认状态码,自定义返回消息,无返回数据
*
* @param msg 自定义返回消息
* @param <T> 返回类泛型
* @return 通用返回Result
*/
public static <T> ResponseResult<T> success(String msg) {
return new ResponseResult<T>(msg);
}
/**
* 成功,默认状态码,自定义返回消息,返回数据
*
* @param msg 自定义返回消息
* @param data 自定义返回数据
* @param <T> 返回类泛型
* @return 通用返回Result
*/
public static <T> ResponseResult<T> success(String msg, T data) {
return new ResponseResult<T>(msg, data);
}
/**
* 失败,默认状态码,返回消息,无返回数据
*
* @param <T> 返回类泛型
* @return 通用返回Result
*/
public static <T> ResponseResult<T> error() {
return new ResponseResult<T>(ResultCode.ERROR);
}
/**
* 失败,默认状态码,自定义返回消息,无返回数据
*
* @param <T> 返回类泛型
* @return 通用返回Result
*/
public static <T> ResponseResult<T> error(String msg) {
return new ResponseResult<T>(ResultCode.ERROR.getCode(), msg);
}
/**
* 失败,自定义状态码,返回消息,无返回数据
*
* @param code 自定义状态码
* @param msg 自定义返回消息
* @param <T> 返回类泛型
* @return 通用返回Result
*/
public static <T> ResponseResult<T> error(int code, String msg) {
return new ResponseResult<T>(code, msg);
}
/**
* 失败,使用CodeMsg状态码,返回消息,无返回数据
*
* @param resultCode CodeMsg,参数如下:
* <p> code 状态码
* <p> msg 返回消息
* @param <T> 返回类泛型
* @return 通用返回Result
*/
public static <T> ResponseResult<T> error(ResultCode resultCode) {
return new ResponseResult<T>(resultCode);
}
/**
* 成功构造器,无返回数据
*/
private ResponseResult() {
this(ResultCode.SUCCESS);
}
/**
* 成功构造器,自定义返回数据
*
* @param data 返回数据
*/
private ResponseResult(T data) {
this(ResultCode.SUCCESS, data);
}
/**
* 成功构造器,自定义返回消息,无返回数据
*
* @param msg 返回消息
*/
public ResponseResult(String msg) {
this(ResultCode.SUCCESS.getCode(), msg);
}
/**
* 成功构造器,自定义返回信息,返回数据
*
* @param msg 返回信息
* @param data 返回数据
*/
private ResponseResult(String msg, T data) {
this(ResultCode.SUCCESS.getCode(), msg, data);
}
/**
* 构造器,自定义状态码,返回消息
*
* @param code 状态码
* @param msg 返回消息
*/
private ResponseResult(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 构造器,自定义状态码,返回消息,返回数据
*
* @param code 状态码
* @param msg 返回消息
* @param data 返回数据
*/
private ResponseResult(int code, String msg, T data) {
this(code, msg);
this.data = data;
}
/**
* 构造器,使用CodeMsg状态码与返回信息
*
* @param resultCode CodeMsg,参数如下:
* <p> code 状态码
* <p> msg 返回消息
*/
private ResponseResult(ResultCode resultCode) {
this(resultCode.getCode(), resultCode.getMsg());
}
/**
* 构造器,使用CodeMsg状态码与返回信息,自定义返回数据
*
* @param resultCode CodeMsg,参数如下:
* <p> code 状态码
* <p> msg 返回消息
* @param data 返回数据
*/
private ResponseResult(ResultCode resultCode, T data) {
this(resultCode);
this.data = data;
}
}
5.异常自定义、异常捕获
5.1 异常自定义
/**
* @author 黔程似景
* @description 自定义异常
* @date 2022/8/21 18:15
* @blame 黔程似景
**/
public class MyException extends Exception {
/**
* 错误码
*/
private int code;
/**
* 错误消息
*/
private String message;
public MyException(int code , String message){
this.code = code;
this.message = message;
}
public MyException() {
}
/**
* Returns the detail message string of this throwable.
*/
@Override
public String getMessage() {
if (super.getMessage() == null){
return this.message;
}
return super.getMessage();
}
/**
* 获取
* @return code
*/
public int getCode() {
return code;
}
/**
* 设置
* @param code
*/
public void setCode(int code) {
this.code = code;
}
/**
* 设置
* @param message
*/
public void setMessage(String message) {
this.message = message;
}
}
5.2 异常捕获
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @author 黔程似景
* @description 异常拦截处理
* @date 2022/8/21 16:42
* @blame 黔程似景
**/
@RestControllerAdvice
public class GlobalExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 空指针异常处理
*/
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult<String> handleTypeMismatchException(NullPointerException exception) {
logger.error("空指针异常:" , exception);
return ResponseResult.error(500, "空指针异常");
}
/**
* 自定义异常处理
*/
@ExceptionHandler(MyException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult myExceptionHandler(MyException exception) {
logger.error("自定义异常:" , exception);
return ResponseResult.error(exception.getCode(), exception.getMessage());
}
/**
* 运行时异常处理
*/
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult throwable(RuntimeException exception) {
logger.error("运行时异常:" , exception);
return new ResponseResult<String>("运行时异常:" + exception.getMessage());
}
/**
* 系统异常处理
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult exception(Exception exception) {
logger.error("系统异常:" , exception);
return new ResponseResult<String>("异常: " + exception.getMessage());
}
}
6.controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 黔程似景
* @description 异常处理接口
* @date 2022/8/22 21:41
* @blame 黔程似景
**/
@RestController
public class ExceptionController {
@GetMapping("/success")
public ResponseResult demo(){
return ResponseResult.success("访问成功!");
}
/**
* 空指针
*/
@GetMapping("/null")
public ResponseResult nullPoint(){
throw new NullPointerException("空指针异常");
}
/**
* 自定义异常
*/
@GetMapping("/myException")
public ResponseResult myException() throws MyException {
throw new MyException(500,"自定义异常");
}
/**
* 运行异常
*/
@GetMapping("/runtimeException")
public ResponseResult runtimeException() {
int a = 1/0;
return null;
}
/**
* 异常
*/
@GetMapping("/exception")
public ResponseResult exception() throws Exception {
throw new Exception("系统异常");
}
}
7.启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 黔程似景
* @description 启动类
* @date 2022/8/22 21:40
* @blame 黔程似景
**/
@SpringBootApplication
public class ExceptionApplication {
public static void main(String[] args) {
SpringApplication.run(ExceptionApplication.class, args);
}
}