Spring Cloud 如何统一异常处理?写得太好了!

2022-06-16 00:00:00 请求 异常 自定义 在线 错误信息


作者:BNDong
链接:www.cnblogs.com/bndong/p/10135370.html

前言

在启动应用时会发现在控制台打印的日志中出现了两个路径为 {[/error]} 的访问地址,当系统中发送异常错误时,Spring Boot 会根据请求方式分别跳转到以 JSON 格式或以界面显示的 /error 地址中显示错误信息。

2018-12-18 09:36:24.627  INFO 19040 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" ...
2018-12-18 09:36:24.632  INFO 19040 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" ...

Spring Boot 基础就不介绍了,推荐下这个实战教程:

https://github.com/javastacks/spring-boot-best-practice

默认异常处理

使用 AJAX 方式请求时返回的 JSON 格式错误信息。

{
    "timestamp""2018-12-18T01:50:51.196+0000",
    "status"404,
    "error""Not Found",
    "message""No handler found for GET /err404",
    "path""/err404"
}

使用浏览器请求时返回的错误信息界面。

自定义异常处理

引入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.54</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

fastjson 是 JSON 序列化依赖, spring-boot-starter-freemarker 是一个模板引擎,用于我们设置错误输出模板。新 Spring Boot 面试题整理好了,大家可以在Java面试库小程序在线刷题。

增加配置

# 出现错误时, 直接抛出异常(便于异常统一处理,否则捕获不到404)
spring.mvc.throw-exception-if-no-handler-found=true
# 不要为工程中的资源文件建立映射
spring.resources.add-mappings=false
spring:
  # 出现错误时, 直接抛出异常(便于异常统一处理,否则捕获不到404)
  mvc:
    throw-exception-if-no-handler-found: true
  # 不要为工程中的资源文件建立映射
  resources:
    add-mappings: false

Spring Boot 基础就不介绍了,推荐下这个实战教程:

https://github.com/javastacks/spring-boot-best-practice

新建错误信息实体

/**
 * 信息实体
 */
public class ExceptionEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    private String message;

    private int    code;

    private String error;

    private String path;

    @JSONField(format = "yyyy-MM-dd hh:mm:ss")
    private Date timestamp = new Date();

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }
}

新建自定义异常

/**
 * 自定义异常
 */
public class BasicException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private int code = ;

    public BasicException(int code, String message) {
        super(message);
        this.code = code;
    }

    public int getCode() {
        return this.code;
    }
}
/**
 * 业务异常
 */
public class BusinessException extends BasicException {

    private static final long serialVersionUID = 1L;

    public BusinessException(int code, String message) {
        super(code, message);
    }
}

BasicException 继承了 RuntimeException ,并在原有的 Message 基础上增加了错误码 code 的内容。而 BusinessException 则是在业务中具体使用的自定义异常类,起到了对不同的异常信息进行分类的作用。分享资料:Spring Boot 学习笔记

新建 error.ftl 模板文件

                

Exception Datas

                                                                                                                                                                                                                                
Code                ${(exception.code)!}            
Time                ${(exception.timestamp?datetime)!}            
Path                ${(exception.path)!}            
Exception                ${(exception.error)!}            
Message                ${(exception.message)!}            

相关文章