技术分享 | Spring Boot 异常处理
说到异常处理,我们都知道使用 try-catch 可以捕捉异常,可以 throws 抛出异常。那么在 Spring Boot 中我们如何处理异常,如何更优雅的处理异常,如何全局处理异常。是本章讨论解决的问题。
-
Java 异常类
首先让我们简单了解或重新学习下 Java 的异常机制。
Java 内部的异常类 Throwable 包括了 Exception 和 Error 两大类,所有的异常类都是 Object 对象。
Error 是不可捕捉的异常,通俗的说就是由于 Java 内部 JVM 引起的不可预见的异常, Java 虚拟机会选择终止线程。如 OutOfMemoryError ,就是 Java 虚拟机运行过程中出现内存资源错误抛出的。
Excetpion 异常是程序本身引起的,它又分为运行时异常 RuntimeException,和非运行时(编译时)IOException 等异常。如除数为零时引发的 ArrayIndexOutOfBoundException 异常就是运行时异常。非运行异常都是可查可捕捉的。Java 编译器会告诉程序他错了,错在哪里,正确的建议什么。我们可以通过 throws 配合 try-catch 来处理。
-
Java 异常处理机制
在 Java 应用程序中,异常处理机制为:抛出异常,捕捉异常。
抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含异常类型和出现异常时的程序运行时信息。运行时系统负责寻找处置异常的代码并执行。
捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(Exception Handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。
当异常处理器能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。
当运行时系统遍历调用栈而未找到合适 的异常处理器,则运行时系统终止。同时,意味着 Java 程序的终止。
-
Spring Boot 异常处理
Spring Boot 的所有异常处理都基于 java 的。
在 Spring Boot 应用程序中,通常统一处理异常的方法有 使用注解处理 RestControllerAdvice
本示例主要目的处理我们日常 Spring Boot 中的异常处理
在 Web 项目中通过 ControllerAdvice、RestControllerAdvice 实现全局异常处理
ControllerAdvice 和 RestControllerAdvice 的区别 相当于 Controller 和 RestController 的区别。
代码示例
添加配置类
-
GlobalExceptionHandler.java
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler({Exception.class})
public Object exceptionHandler(Exception e){
Map<String,Object> map=new HashMap<>();
map.put("status",-1);
map.put("msg",e.getLocalizedMessage());
return map;
}
}
-
配置介绍
RestControllerAdvice:全局捕获异常,异常集中处理,更好的使业务逻辑与异常处理剥离开,定义在类上
ExceptionHandler:统一处理某一类异常,声明该方法用于捕获 value 所指的类型的异常(注意:当该异常的子父类都被声明时,按照先子后父的顺序进行捕获)
ResponseStatus:将某种异常映射为 HTTP 状态码,可用在方法上,也可以用在类上(自定义运行时异常类)。
添加模拟异常接口
-
HogwartsTestUserController.java
在 HogwartsTestUserController.java 新增一个 error 接口
/**
* 模拟抛出异常
* */
@GetMapping("/error")
public Object err(){
throw new RuntimeException("抛出一个异常");
}
使用 Postman 进行测试
GET http://127.0.0.1:8081/api/user/users/3 正常返回
{
"id": 3,
"name": "HogwartsTest2",
"pwd": "HogwartsTest2"
}
GET http://127.0.0.1:8081/api/user/error 抛出异常,并给出提示信息
{ "msg": "抛出一个异常", "status": -1 }
相关文章
- spring-boot打包,引入外部jar包问题
- spring security 注解@EnableGlobalMethodSecurity详解
- 【Spring Boot】Spring Boot之两种引入spring boot maven依赖的方式
- spring boot项目如何测试,如何部署
- spring boot: 热部署spring-boot-devtools
- Spring MVC文件上传教程 commons-io/commons-uploadfile
- Spring Boot自动配置源码
- 解决Spring Boot OTS parsing error: Failed to convert WOFF 2.0
- spring boot 实现定时任务
- spring boot下JedisCluster方式连接Redis集群的配置
- [Spring学习笔记 3 ] spring 注解详解,完全注解,常用注解
- Spring Boot——2分钟构建spring web mvc REST风格HelloWorld
- [Spring] 声明Bean
- spring boot:实现图片文件上传并生成缩略图(spring boot 2.3.1)
- 探究Spring Cloud Elasticsearch:最佳性能调优技巧
- 学习Spring Boot:(十四)spring-shiro的密码加密
- 自我分析-Spring IOC
- 解决com.alibaba.fastjson.JSONException: write javaBean error问题以及解决Spring Boot加入Shiro导致spring aop失效的问题
- Quick Guide to Microservices with Spring Boot 2.0, Eureka and Spring Cloud
- Spring依赖注入(五):盘一盘Spring的三级缓存
- Java Spring框架是什么?它有哪些好处?
- [spring学习]10、AOP思想提出
- 【java】Spring Cloud--Feign 基本使用