SpringBoot中异常处理
2022-04-28 16:04
681 查看
一、背景
在我们编写程序的过程中,程序中可能随时发生各种异常,那么我们如何优雅的处理各种异常呢?
二、需求
1、拦截系统中部分异常,返回自定义的响应。
比如: 系统发生
HttpRequestMethodNotSupportedException异常,我们需要返回如下信息。 http的状态码:返回
405
{ code: 自定义异常码, message: 错误消息 }
2、实现自定义异常的拦截
拦截我们自己写的
BizException
三、编写一些异常基础代码
1、引入jar包
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> </dependencies>
注意: 引入
spring-boot-starter-validation是为了验证请求的中的参数,然后当参数不满足时抛出异常。
2、定义一个自定义异常
public class BizException extends RuntimeException { public BizException() { } public BizException(String message) { super(message); } public BizException(String message, Throwable cause) { super(message, cause); } public BizException(Throwable cause) { super(cause); } public BizException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
3、编写一个简单的控制层
@RestController @RequestMapping("exception") public class ExceptionTestController { static class Req { @NotBlank public String password; } @PostMapping("password") public String checkPassword(@Validated @RequestBody Req req) { if (Objects.equals(req.password, "exception")) { throw new BizException("密码传递的是exception字符串"); } return "当前密码,password: " + req.password; } }
解释 提供一个
/exception/passwordapi,需要传递一个
password参数 1、当不传递 password 参数时将抛出MethodArgumentNotValidException异常。 2、当password传递exception参数时,则抛出BizException异常。
4、测试
1、不传递password参数响应是什么
1、使用默认的DefaultHandlerExceptionResolver处理
这个类
DefaultHandlerExceptionResolver是默认自动配置的。
从上图中可以看出有一个默认字段的返回值
2、使用ResponseEntityExceptionHandler处理
1、编写异常处理代码-使用默认的逻辑
@RestControllerAdvice public class RestExceptionHandler extends ResponseEntityExceptionHandler { @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { // 此处自定义返回值 return super.handleMethodArgumentNotValid(ex, headers, status, request); } }
可以看到
handleMethodArgumentNotValid方法直接调用父类的方法,即使用默认的处理方式。
从上图中可以看出返回值是空
2、编写异常处理代码-返回值返回自定义内容
@Component @RestControllerAdvice public class RestExceptionHandler extends ResponseEntityExceptionHandler { @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { // 此处自定义返回值 return super.handleMethodArgumentNotValid(ex, headers, status, request); } @Override protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { Set<HttpMethod> supportedMethods = ex.getSupportedHttpMethods(); // 自定义请求返回值 Map<String, Object> body = new HashMap<>(4); body.put("code", "错误码"); body.put("message", "当前请求的方法不支持,支持的请求方法为:" + supportedMethods); return new ResponseEntity<>(body, headers, status); } }
由上面的代码可知
handleHttpRequestMethodNotSupported方法返回了自定义的body。
从上图中可以看出,返回了我们自己定义的返回值。
2、password参数传递exception
1、使用ResponseEntityExceptionHandler或DefaultHandlerExceptionResolver处理
由上图可知返回结果不对,我们需要自定义返回结果。
2、返回自定义异常
1、编写BizException处理代码
@RestControllerAdvice public class BizExceptionHandler { @ExceptionHandler(BizException.class) public ResponseEntity<Object> handleBizException(BizException exception) { // 自定义请求返回值 Map<String, Object> body = new HashMap<>(4); body.put("code", "错误码"); body.put("message", "异常信息为:" + exception.getMessage()); return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR); } }
2、测试返回结果
从上图可知返回了自定义信息
四、注意事项
1、如果实现自定义异常处理
- 类上使用
@RestControllerAdvice
注解 - 方法上使用
@ExceptionHandler
来处理特定的异常
2、ResponseEntityExceptionHandler默认处理那些异常
3、使用了ResponseEntityExceptionHandler后,为什么发生了异常后返回体为空
默认情况下,实现了
ResponseEntityExceptionHandler这个类后,这个类处理的所有异常的响应结果都是
null,如果想返回别的值需要我们自己去处理。
五、总结
1、如果我们想处理自定义异常,则可以使用
@RestControllerAdvice||
@ControllerAdvice配置
@ExceptionHandler来使用。 2、如果我们实现了
ResponseEntityExceptionHandler来处理异常,那么默认的异常的响应结果为空,如果想不为空,则需要我们自己处理。 3、默认情况下,标准的Spring MVC异常会通过
DefaultHandlerExceptionResolver来处理。
六、代码实现
https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-exception-handler
七、参考文档
相关文章推荐
- SpringBoot 异常处理,数据校验
- Springboot全局异常处理
- SpringBoot全局异常处理
- Spring-Boot(五) 全局异常处理
- Spring Boot中Web应用的统一异常处理
- SpringBoot如何优雅的处理全局异常
- 如何优雅的处理Spring Boot异常信息详解
- springboot异常处理解析
- Spring Boot统一异常处理详解
- Spring Boot 中关于自定义异常处理的套路!
- SpringBoot异常处理的5种方式
- spring boot - cloud (二) 规范响应格式以及统一异常处理
- SpringBoot入门——局部与全局的异常处理
- springboot + shiro 权限注解、统一异常处理、请求乱码解决
- SpringBoot使用统一异常处理详解
- SpringBoot学习-(二十一)SpringBoot异常统一处理
- Spring Boot全局异常捕获处理
- SpringBoot如何优雅地处理全局异常详解
- SpringBoot 2.x(七):优雅的处理异常
- Spring Boot整合thymeleaf并进行异常处理