当前位置: 首页 > 科技观察

SpringBoot处理异常的几种常见姿势

时间:2023-03-11 20:15:32 科技观察

1、使用@ControllerAdvice和@ExceptionHandler来处理全局异常这是目前很常见的一种方式,强烈推荐。测试代码中使用了Junit5。如果你新建一个项目来验证下面的代码,记得添加相关的依赖。1.新建一个异常信息实体类,这个不是必须的,主要用来封装异常信息。src/main/java/com/twuc/webApp/exception/ErrorResponse.java/***@authorshuang.kou*/publicclassErrorResponse{privateStringmessage;privateStringerrorTypeName;publicErrorResponse(Exceptione){this(e.getClass().getName(),e.getMessage());}publicErrorResponse(StringerrorTypeName,Stringmessage){this.errorTypeName=errorTypeName;this.message=message;}......省略getter/setter方法}2.自定义异常类型src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java一般我们处理RuntimeException,所以如果需要自定义异常类型,直接集成这个类即可。/***@authorshuang.kou*自定义异常类型*/publicclassResourceNotFoundExceptionextendsRuntimeException{privateStringmessage;publicResourceNotFoundException(){super();}publicResourceNotFoundException(Stringmessage){super(message);this.message=message;}@OverridepublicStringgetMessage(){returnmessage;}publicvoidsetMessage(Stringmessage){this.message=message;}}3.新建一个异常处理类,我们只需要在该类上加上@ControllerAdvice注解,就可以成为一个全局的异常处理类。当然你也可以通过assignableTypes指定一个具体的Controller类,让异常处理类只处理具体类抛出的异常。src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java/***@authorshuang.kou*/@ControllerAdvice(assignableTypes={ExceptionController.class})@ResponseBodypublicclassGlobalExceptionHandler{ErrorResponseillegalArgumentResponse=newEx"ErrorResponse(参数错误!"));ErrorResponseresourseNotFoundResponse=newErrorResponse(newResourceNotFoundException("Sorry,theresoursenotfound!"));@ExceptionHandler(value=Exception.class)//拦截所有异常,这里只是为了演示,一般情况下,一个方法专门处理异常publicResponseEntity4.controller模拟抛异常src/main/java/com/twuc/webApp/web/ExceptionController.java/***@authorshuang.kou*/@RestController@RequestMapping("/api")publicclassExceptionController{@GetMapping("/illegalArgumentException")publicvoidthrowException(){thrownewIllegalArgumentException();}@GetMapping("/resourceNotFoundException")publicvoidthrowException2(){thrownewResourceNotFoundException();}}使用Get请求localhost:8080/api/resourceNot(curl-i-s-XGETurl),服务器返回的JSON数据如下:{"message":"Sorry,theresoursenotfound!","errorTypeName":"com.twuc.webApp.exception.ResourceNotFoundException"}5.编写org.springframework.boot.test包提供的测试类MockMvc,实现模拟Http请求,一般用于我们测试controller层/***@authorshuang.kou*/@AutoConfigureMockMvc@SpringBootTestpublicclassExceptionTest{@AutowiredMockMvcmockMvc;@Testvoidshould_return_400_if_param_not_valid()throwsException{mockMvc.perform(get("/api/illegalArgumentException0(0))).andExpect(状态.andExpect(jsonPath("$.message").value("参数错误!"));}@Testvoidshould_return_404_if_resourse_not_found()throwsException{mockMvc.perform(get("/api/resourceNotFoundException")).andExpect(status().is(404))。andExpect(jsonPath("$.message").value("Sorry,theresoursenotfound!"));}}二、@ExceptionHandler在Controller层面处理异常我们刚刚说过使用@ControllerAdvice注解可以通过assignableTypes指定具体的类,使得异常处理类只处理特定类抛出的异常。所以这种处理异常的方式现在其实用的比较少。我们把下面的代码移到src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler。爪哇。@ExceptionHandler(value=Exception.class)//剔除所有异常publicResponseEntityexceptionHandler(Exceptione){if(einstanceofIllegalArgumentException){returnResponseEntity.status(400).body(illegalArgumentResponse);}elseif(einstanceofResourceNotFoundException){returnResponse(Entity.404).body(resourseNotFoundResponse);}returnnull;}3.ResponseStatusExceptionResponseStatusException的研究下面我们来看看通过ResponseStatus注解(将异常映射到状态码)处理异常的简单方法。src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java@ResponseStatus(code=HttpStatus.NOT_FOUND)publicclassResourseNotFoundException2extendsRuntimeException{publicResourseNotFoundException2(){}publicResourseNotFoundException2(){}publicResourseNotFoundException2(String}消息)/superage/java(消息)/com/twuc/webApp/web/ResponseStatusExceptionController.java@RestController@RequestMapping("/api")publicclassResponseStatusExceptionController{@GetMapping("/resourceNotFoundException2")publicvoidthrowException3(){thrownewResourseNotFoundException2("对不起,资源)}获取!请求本地主机:8080/api/resourceNotFoundException2[2],服务器返回的json数据如下:{"timestamp":"2019-08-21T07:11:43.744+0000","status":404,"error":"NotFound","message":"Sorry,theresoursenotfound!","path":"/api/resourceNotFoundException2"}这种通过ResponseStatus注解简单处理异常的方法比较简单,但是一般我们不会这样做,通过ResponseStatusException会更方便,可以避免我们额外的异常类@GetMapping("/resourceNotFoundException2")publicvoidthrowException3(){thrownewResponseStatusException(HttpStatus.NOT_FOUND,"Sorry,theresoursenotfound!",newResourceNotFoundException());}使用服务器返回的JSON请求localhost:8080/api/resourceNotFoundException2[3]数据如下,与使用ResponseStatus一样:{"timestamp":"2019-08-21T07:28:12.017+0000","status":404,"error":"NotFound","message":"Sorry,theresoursenotfound!","path":"/api/resourceNotFoundException3"}ResponseStatusException提供了三种构造方法:状态,原因,null);}publicResponseStatusException(HttpStatusstatus,@NullableStringreason,@NullableThrowablecause){super(null,cause);Assert.notNull(status,"HttpStatusisrequired");this.status=status;this.reason=reason;}构造函数中的参数解释如下:?status:http状态?reason:响应的消息内容?cause:抛出的异常