SpringBoot中异常处理实战记录

作者:huan1993 时间:2022-07-21 20:39:01 

一、背景

在我们编写程序的过程中,程序中可能随时发生各种异常,那么我们如何优雅的处理各种异常呢?

二、需求

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);
   }
}

解释

提供一个 /exception/password api,需要传递一个password参数

1、当不传递 password 参数时将抛出MethodArgumentNotValidException异常。

2、当password传递exception参数时,则抛出BizException异常。

4、测试

1、不传递password参数响应是什么

1、使用默认的DefaultHandlerExceptionResolver处理

这个类DefaultHandlerExceptionResolver是默认自动配置的。

SpringBoot中异常处理实战记录

从上图中可以看出有一个默认字段的返回值

SpringBoot中异常处理实战记录

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方法直接调用父类的方法,即使用默认的处理方式。

SpringBoot中异常处理实战记录

从上图中可以看出返回值是空

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。

SpringBoot中异常处理实战记录

从上图中可以看出,返回了我们自己定义的返回值。

2、password参数传递exception1、使用ResponseEntityExceptionHandler或DefaultHandlerExceptionResolver处理

SpringBoot中异常处理实战记录

由上图可知返回结果不对,我们需要自定义返回结果。

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、测试返回结果

SpringBoot中异常处理实战记录

从上图可知返回了自定义信息

四、注意事项

1、如果实现自定义异常处理类上使用@RestControllerAdvice注解方法上使用@ExceptionHandler来处理特定的异常

2、ResponseEntityExceptionHandler默认处理那些异常

SpringBoot中异常处理实战记录

3、使用了ResponseEntityExceptionHandler后,为什么发生了异常后返回体为空

SpringBoot中异常处理实战记录

默认情况下,实现了 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中异常处理实战记录

来源:https://www.cnblogs.com/huan1993/p/16203226.html

标签:springboot,异常,处理
0
投稿

猜你喜欢

  • java获取百度网盘真实下载链接的方法

    2021-09-07 21:16:08
  • java substring 截取字符串的方法

    2023-02-12 17:21:19
  • Android实现自定义的卫星式菜单(弧形菜单)详解

    2023-03-03 14:16:51
  • Android 触摸事件监听(Activity层,ViewGroup层,View层)详细介绍

    2023-02-07 00:58:51
  • unity实现场景跳转

    2023-08-30 22:58:15
  • 一文搞懂并学会使用SpringBoot的Actuator运行状态监控组件的详细教程

    2022-01-31 10:28:23
  • Android开发中amera2 Preview使用详解

    2023-11-09 20:17:56
  • 利用spring aop实现动态代理

    2022-02-02 16:50:25
  • C#切换鼠标左右键习惯无需控制面板中修改

    2021-08-06 04:44:44
  • spring boot的maven配置依赖详解

    2021-09-30 12:37:53
  • 一文让你搞懂如何手写一个redis分布式锁

    2023-11-29 02:46:30
  • @TransactionalEventListener的使用和实现原理分析

    2022-01-19 06:15:11
  • Netty分布式Future与Promise执行回调相关逻辑剖析

    2021-08-18 23:33:50
  • 合并有序数组的实现(java与C语言)

    2023-08-16 13:45:40
  • java实现切割wav音频文件的方法详解【附外部jar包下载】

    2021-07-08 22:29:56
  • WPF实现自带触控键盘的文本框

    2023-08-25 15:23:20
  • SpringBoot项目中遇到的BUG问题及解决方法

    2022-01-19 14:44:38
  • java多线程之线程同步七种方式代码示例

    2022-04-29 17:55:46
  • C#实现加密的几种方法介绍

    2022-12-12 22:38:00
  • C#实现登录窗口(不用隐藏)

    2021-11-21 09:30:24
  • asp之家 软件编程 m.aspxhome.com