时间:2021-05-19
一、使用 @ControllerAdvice 和 @ExceptionHandler 处理全局异常
这是目前很常用的一种方式,非常推荐。测试代码中用到了 Junit 5,如果你新建项目验证下面的代码的话,记得添加上相关依赖。
1. 新建异常信息实体类
非必要的类,主要用于包装异常信息。
src/main/java/com/twuc/webApp/exception/ErrorResponse.java
/** * @author shuang.kou */ public class ErrorResponse { private String message; private String errorTypeName; public ErrorResponse(Exception e) { this(e.getClass().getName(), e.getMessage()); } public ErrorResponse(String errorTypeName, String message) { this.errorTypeName = errorTypeName; this.message = message; } ......省略getter/setter方法 }2. 自定义异常类型
src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java
一般我们处理的都是 RuntimeException ,所以如果你需要自定义异常类型的话直接集成这个类就可以了。
/** * @author shuang.kou * 自定义异常类型 */ public class ResourceNotFoundException extends RuntimeException { private String message; public ResourceNotFoundException() { super(); } public ResourceNotFoundException(String message) { super(message); this.message = message; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }3. 新建异常处理类
我们只需要在类上加上@ControllerAdvice注解这个类就成为了全局异常处理类,当然你也可以通过 assignableTypes指定特定的 Controller 类,让异常处理类只处理特定类抛出的异常。
src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java
/** * @author shuang.kou */ @ControllerAdvice(assignableTypes = {ExceptionController.class}) @ResponseBody public class GlobalExceptionHandler { ErrorResponse illegalArgumentResponse = new ErrorResponse(new IllegalArgumentException("参数错误!")); ErrorResponse resourseNotFoundResponse = new ErrorResponse(new ResourceNotFoundException("Sorry, the resourse not found!")); @ExceptionHandler(value = Exception.class)// 拦截所有异常, 这里只是为了演示,一般情况下一个方法特定处理一种异常 public ResponseEntity<ErrorResponse> exceptionHandler(Exception e) { if (e instanceof IllegalArgumentException) { return ResponseEntity.status(400).body(illegalArgumentResponse); } else if (e instanceof ResourceNotFoundException) { return ResponseEntity.status(404).body(resourseNotFoundResponse); } return null; } }4. controller模拟抛出异常
src/main/java/com/twuc/webApp/web/ExceptionController.java
/** * @author shuang.kou */ @RestController @RequestMapping("/api") public class ExceptionController { @GetMapping("/illegalArgumentException") public void throwException() { throw new IllegalArgumentException(); } @GetMapping("/resourceNotFoundException") public void throwException2() { throw new ResourceNotFoundException(); } }使用 Get 请求 localhost:8080/api/resourceNotFoundException[1] (curl -i -s -X GET url),服务端返回的 JSON 数据如下:
{ "message": "Sorry, the resourse not found!", "errorTypeName": "com.twuc.webApp.exception.ResourceNotFoundException" }5. 编写测试类
MockMvc 由org.springframework.boot.test包提供,实现了对Http请求的模拟,一般用于我们测试 controller 层。
/** * @author shuang.kou */ @AutoConfigureMockMvc @SpringBootTest public class ExceptionTest { @Autowired MockMvc mockMvc; @Test void should_return_400_if_param_not_valid() throws Exception { mockMvc.perform(get("/api/illegalArgumentException")) .andExpect(status().is(400)) .andExpect(jsonPath("$.message").value("参数错误!")); } @Test void should_return_404_if_resourse_not_found() throws Exception { mockMvc.perform(get("/api/resourceNotFoundException")) .andExpect(status().is(404)) .andExpect(jsonPath("$.message").value("Sorry, the resourse not found!")); } }二、 @ExceptionHandler 处理 Controller 级别的异常
我们刚刚也说了使用@ControllerAdvice注解 可以通过 assignableTypes指定特定的类,让异常处理类只处理特定类抛出的异常。所以这种处理异常的方式,实际上现在使用的比较少了。
我们把下面这段代码移到 src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java 中就可以了。
@ExceptionHandler(value = Exception.class)// 拦截所有异常 public ResponseEntity<ErrorResponse> exceptionHandler(Exception e) { if (e instanceof IllegalArgumentException) { return ResponseEntity.status(400).body(illegalArgumentResponse); } else if (e instanceof ResourceNotFoundException) { return ResponseEntity.status(404).body(resourseNotFoundResponse); } return null; }三、 ResponseStatusException
研究 ResponseStatusException 我们先来看看,通过 ResponseStatus注解简单处理异常的方法(将异常映射为状态码)。
src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java
@ResponseStatus(code = HttpStatus.NOT_FOUND) public class ResourseNotFoundException2 extends RuntimeException { public ResourseNotFoundException2() { } public ResourseNotFoundException2(String message) { super(message); } }src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java
@RestController @RequestMapping("/api") public class ResponseStatusExceptionController { @GetMapping("/resourceNotFoundException2") public void throwException3() { throw new ResourseNotFoundException2("Sorry, the resourse not found!"); } }使用 Get 请求 localhost:8080/api/resourceNotFoundException2[2] ,服务端返回的 JSON 数据如下:
{ "timestamp": "2019-08-21T07:11:43.744+0000", "status": 404, "error": "Not Found", "message": "Sorry, the resourse not found!", "path": "/api/resourceNotFoundException2" }这种通过 ResponseStatus注解简单处理异常的方法是的好处是比较简单,但是一般我们不会这样做,通过ResponseStatusException会更加方便,可以避免我们额外的异常类。
@GetMapping("/resourceNotFoundException2") public void throwException3() { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Sorry, the resourse not found!", new ResourceNotFoundException()); }使用 Get 请求 localhost:8080/api/resourceNotFoundException2[3] ,服务端返回的 JSON 数据如下,和使用 ResponseStatus 实现的效果一样:
{ "timestamp": "2019-08-21T07:28:12.017+0000", "status": 404, "error": "Not Found", "message": "Sorry, the resourse not found!", "path": "/api/resourceNotFoundException3" }ResponseStatusException 提供了三个构造方法:
public ResponseStatusException(HttpStatus status) { this(status, null, null); } public ResponseStatusException(HttpStatus status, @Nullable String reason) { this(status, reason, null); } public ResponseStatusException(HttpStatus status, @Nullable String reason, @Nullable Throwable cause) { super(null, cause); Assert.notNull(status, "HttpStatus is required"); this.status = status; this.reason = reason; }构造函数中的参数解释如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
今天继续讲解java中的异常处理机制,主要介绍Exception家族的主要成员,自定义异常,以及异常处理的正确姿势。Exception家族 一图胜千言,先
Java异常处理运行时异常(RuntimeException)详解及实例RuntimeExceptionRunntimeException的子类:ClassCa
本文首先将会回顾Spring5之前的SpringMVC异常处理机制,然后主要讲解SpringBoot2Webflux的全局异常处理机制。SpringMVC的异常
为什么需要全局异常处理在传统SpringBoot应用中,我们@ControllerAdvice来处理全局的异常,进行统一包装返回//摘至springclouda
本文为大家分享了SpringBoot全局异常处理,供大家参考,具体内容如下1、后台处理异常a、引入thymeleaf依赖org.springframework.