当前位置: 首页 > 后端技术 > Java

SpringBoot中的异常处理

时间:2023-04-01 22:00:03 Java

一、背景在编写程序的过程中,程序中随时可能出现各种异常,那么我们如何优雅地处理各种异常呢?二、需求1、拦截系统中的一些异常,返回自定义响应。比如系统出现HttpRequestMethodNotSupportedException,我们需要返回如下信息。HTTP状态码:return405{code:自定义异常代码,message:错误信息}2、实现自定义异常的拦截,拦截自己写的BizException3、编写一些基本的异常代码1、引入jar包org.springframework.bootspring-boot-starter-weborg.springframework.boot春天-boot-starter-validation注:spring-boot-starter-validation的引入是对请求中的参数进行校验,当参数不满足时抛出异常.2.定义自定义异常publicclassBizExceptionextendsRuntimeException{publicBizException(){}publicBizException(Stringmessage){super(message);}publicBizException(Stringmessage,Throwablecause){super(message,cause);}publicBizException(Throwablecause){super(cause);}publicBizException(Stringmessage,Throwablecause,booleanenableSuppression,booleanwritableStackTrace){super(message,cause,enableSuppression,writableStackTrace);}}3.写一个简单的控制层@RestController@RequestMapping("exception")publicclassExceptionTestController{staticclassReq{@NotBlankpublicStringpassword;}@PostMapping("password")publicStringcheckPassword(@Validated@RequestBodyReqreq){if(Objects.equals(req.password,"exception")){thrownewBizException("传递的密码是异常字符串");}返回“当前Password,password:"+req.password;}}说明提供一个/exception/passwordapi,需要传递一个password参数。1.当不传递password参数时,会抛出一个MethodArgumentNotValidException。2.当password传递异常参数,会抛出BizException。4.测试1.不传递password参数的响应是什么?1.使用默认的DefaultHandlerExceptionResolver来处理这个类,DefaultHandlerExceptionResolver默认是自动配置的。从上图可以看出有一个默认字段的返回值2.使用ResponseEntityExceptionHandler处理1.编写异常处理代码-使用默认逻辑MethodArgumentNotValidExceptionex,HttpHeadersheaderscustomquereturn){returnherestatus,HttpWebStatussuper.handleMethodArgumentNotValid(ex,headers,status,request);}}}可以看到handleMethodArgumentNotValid方法是直接调用父类的方法,即使用默认的处理方式。从上图可以看出返回值为空2.编写异常处理代码-返回值返回自定义内容,WebRequestrequest){//这里自定义返回值returnsuper.handleMethodArgumentNotValid(ex,headers,status,request);}@OverrideprotectedResponseEntityhandleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedExceptionex,HttpHeadersheaders,HttpStatusstatus,WebRequestrequest){设置supportedMethods=ex.getSupportedHttpMethods();//自定义请求返回值Mapbody=newHashMap<>(4);body.put("代码","错误代码");body.put("message","不支持当前请求的方法,支持的请求方法为:"+supportedMethods);返回新的响应实体<>(正文、标题、状态);}}从上面的代码可以看出,handleHttpRequestMethodNotSupported方法返回了一个自定义的body。从上图可以看出,它返回的是我们自己定义的返回值。2.password参数传递给exception1。使用ResponseEntityExceptionHandler或DefaultHandlerExceptionResolver来处理它。从上图我们可以看出返回的结果是不正确的,需要自定义返回结果。2.返回自定义异常1.编写BizException处理代码@RestControllerAdvicepublicclassBizExceptionHandler{@ExceptionHandler(BizException.class)publicResponseEntityhandleBizException(BizExceptionexception){//自定义请求返回值Mapbody=new哈希图<>(4);body.put("代码","错误代码");body.put("message","异常消息是:"+exception.getMessage());返回新的ResponseEntity<>(body,HttpStatus.INTERNAL_SERVER_ERROR);}}2.上图返回的测试结果显示返回了自定义信息。四、注意事项1、如果实现了自定义的异常处理类,使用@RestControllerAdvice注解方法使用@ExceptionHandler来处理具体的异常2、ResponseEntityExceptionHandler默认处理那些异常3、使用ResponseEntityExceptionHandler后,为什么异常后返回体为空发生?默认情况下,实现ResponseEntityExceptionHandler类后,该类处理的所有异常的响应结果为null。返回其他值需要我们自行处理。五、总结1、如果我们要处理自定义异常,可以使用@RestControllerAdvice||@ControllerAdvice配置要使用的@ExceptionHandler。2、如果我们实现ResponseEntityExceptionHandler来处理异常,那么默认的异常响应结果为空。如果我们希望它不为空,我们需要自己处理。3.默认情况下,标准的SpringMVC异常将由DefaultHandlerExceptionResolver处理。6.代码实现https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-exception-handler7.参考文档