下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

编程语言的SpringBoot 异常怎么处理?

作者:课课家教育     来源: http://www.kokojia.com点击数:937发布时间: 2019-08-30 18:45:56

标签: 编程语言pythonpython教程

大神带你学编程,欢迎选课

SpringBoot 处理异常的几种常见姿势。Python的创始人为Guido van Rossum。1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,作为ABC 语言的一种继承。

之所以选中Python(大蟒蛇的意思)作为该编程语言的名字,是取自英国20世纪70年代首播的电视喜剧《蒙提.派森干的飞行马戏团》(Monty Python's Flying Circus)。

这是目前很常用的一种方式,非常推荐。测试代码中用到了 Junit 5,如果你新建项目验证下面的代码的话,记得添加上相关依赖。

编程语言的SpringBoot 异常怎么处理_编程语言_python_python教程_课课家

一、使用 @ControllerAdvice 和 @ExceptionHandler 处理全局异常

这是目前很常用的一种方式,非常推荐。测试代码中用到了 Junit 5,如果你新建项目验证下面的代码的话,记得添加上相关依赖。

1. 新建异常信息实体类

非必要的类,主要用于包装异常信息。

src/main/java/com/twuc/webapp/exception/ErrorResponse.java

  1. /** 
  2.  * @author shuang.kou 
  3.  */ 
  4. public class ErrorResponse { 
  5.  private String message; 
  6.  private String errorTypeName; 
  7.  public ErrorResponse(Exception e) { 
  8.  this(e.getClass().getName(), e.getMessage()); 
  9.  } 
  10.  public ErrorResponse(String errorTypeName, String message) { 
  11.  this.errorTypeName = errorTypeName; 
  12.  this.message = message; 
  13.  } 
  14.  ......省略getter/setter方法 

2. 自定义异常类型

src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java

一般我们处理的都是 RuntimeException ,所以如果你需要自定义异常类型的话直接集成这个类就可以了。

  1. /** 
  2.  * @author shuang.kou 
  3.  * 自定义异常类型 
  4.  */ 
  5. public class ResourceNotFoundException extends RuntimeException { 
  6.  private String message; 
  7.  public ResourceNotFoundException() { 
  8.  super(); 
  9.  } 
  10.  public ResourceNotFoundException(String message) { 
  11.  super(message); 
  12.  this.message = message; 
  13.  } 
  14.  @Override 
  15.  public String getMessage() { 
  16.  return message; 
  17.  } 
  18.  public void setMessage(String message) { 
  19.  this.message = message; 
  20.  } 

3. 新建异常处理类

我们只需要在类上加上@ControllerAdvice注解这个类就成为了全局异常处理类,当然你也可以通过 assignableTypes指定特定的 Controller 类,让异常处理类只处理特定类抛出的异常。

src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java

  1. /** 
  2.  * @author shuang.kou 
  3.  */ 
  4. @ControllerAdvice(assignableTypes = {ExceptionController.class}) 
  5. @ResponseBody 
  6. public class GlobalExceptionHandler { 
  7.  ErrorResponse illegalArgumentResponse = new ErrorResponse(new IllegalArgumentException("参数错误!")); 
  8.  ErrorResponse resourseNotFoundResponse = new ErrorResponse(new ResourceNotFoundException("Sorry, the resourse not found!")); 
  9.  @ExceptionHandler(value = Exception.class)// 拦截所有异常, 这里只是为了演示,一般情况下一个方法特定处理一种异常 
  10.  public ResponseEntity<ErrorResponse> exceptionHandler(Exception e) { 
  11.  if (e instanceof IllegalArgumentException) { 
  12.  return ResponseEntity.status(400).body(illegalArgumentResponse); 
  13.  } else if (e instanceof ResourceNotFoundException) { 
  14.  return ResponseEntity.status(404).body(resourseNotFoundResponse); 
  15.  } 
  16.  return null
  17.  } 

4. controller模拟抛出异常

src/main/java/com/twuc/webApp/web/ExceptionController.java

  1. /** 
  2.  * @author shuang.kou 
  3.  */ 
  4. @RestController 
  5. @RequestMapping("/api"
  6. public class ExceptionController { 
  7.  @GetMapping("/illegalArgumentException"
  8.  public void throwException() { 
  9.  throw new IllegalArgumentException(); 
  10.  } 
  11.  @GetMapping("/resourceNotFoundException"
  12.  public void throwException2() { 
  13.  throw new ResourceNotFoundException(); 
  14.  } 

使用 Get 请求 localhost:8080/api/resourceNotFoundException[1] (curl -i -s -X GET url),服务端返回的 JSON 数据如下:

  1.  "message""Sorry, the resourse not found!"
  2.  "errorTypeName""com.twuc.webApp.exception.ResourceNotFoundException" 

5. 编写测试类

MockMvc 由org.springframework.boot.test包提供,实现了对Http请求的模拟,一般用于我们测试 controller 层。

  1. /** 
  2.  * @author shuang.kou 
  3.  */ 
  4. @AutoConfigureMockMvc 
  5. @SpringBootTest 
  6. public class ExceptionTest { 
  7.  @Autowired 
  8.  MockMvc mockMvc; 
  9.  @Test 
  10.  void should_return_400_if_param_not_valid() throws Exception { 
  11.  mockMvc.perform(get("/api/illegalArgumentException")) 
  12.  .andExpect(status().is(400)) 
  13.  .andExpect(jsonPath("$.message").value("参数错误!")); 
  14.  } 
  15.  @Test 
  16.  void should_return_404_if_resourse_not_found() throws Exception { 
  17.  mockMvc.perform(get("/api/resourceNotFoundException")) 
  18.  .andExpect(status().is(404)) 
  19.  .andExpect(jsonPath("$.message").value("Sorry, the resourse not found!")); 
  20.  } 

二、 @ExceptionHandler 处理 Controller 级别的异常

我们刚刚也说了使用@ControllerAdvice注解 可以通过 assignableTypes指定特定的类,让异常处理类只处理特定类抛出的异常。所以这种处理异常的方式,实际上现在使用的比较少了。

我们把下面这段代码移到 src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java 中就可以了。

  1. @ExceptionHandler(value = Exception.class)// 拦截所有异常 
  2. public ResponseEntity<ErrorResponse> exceptionHandler(Exception e) { 
  3. if (e instanceof IllegalArgumentException) { 
  4. return ResponseEntity.status(400).body(illegalArgumentResponse); 
  5. else if (e instanceof ResourceNotFoundException) { 
  6. return ResponseEntity.status(404).body(resourseNotFoundResponse); 
  7. return null

三、 ResponseStatusException

研究 ResponseStatusException 我们先来看看,通过 ResponseStatus注解简单处理异常的方法(将异常映射为状态码)。

src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java

  1. @ResponseStatus(code = HttpStatus.NOT_FOUND) 
  2. public class ResourseNotFoundException2 extends RuntimeException { 
  3.  public ResourseNotFoundException2() { 
  4.  } 
  5.  public ResourseNotFoundException2(String message) { 
  6.  super(message); 
  7.  } 

src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java

  1. @RestController 
  2. @RequestMapping("/api"
  3. public class ResponseStatusExceptionController { 
  4.  @GetMapping("/resourceNotFoundException2"
  5.  public void throwException3() { 
  6.  throw new ResourseNotFoundException2("Sorry, the resourse not found!"); 
  7.  } 

使用 Get 请求 localhost:8080/api/resourceNotFoundException2[2] ,服务端返回的 JSON 数据如下:

  1.  "timestamp""2019-08-21T07:11:43.744+0000"
  2.  "status"404
  3.  "error""Not Found"
  4.  "message""Sorry, the resourse not found!"
  5.  "path""/api/resourceNotFoundException2" 

这种通过 ResponseStatus注解简单处理异常的方法是的好处是比较简单,但是一般我们不会这样做,通过ResponseStatusException会更加方便,可以避免我们额外的异常类。

  1. @GetMapping("/resourceNotFoundException2"
  2. public void throwException3() { 
  3. throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Sorry, the resourse not found!"new ResourceNotFoundException()); 

使用 Get 请求 localhost:8080/api/resourceNotFoundException2[3] ,服务端返回的 JSON 数据如下,和使用 ResponseStatus 实现的效果一样:

  1.  "timestamp""2019-08-21T07:28:12.017+0000"
  2.  "status"404
  3.  "error""Not Found"
  4.  "message""Sorry, the resourse not found!"
  5.  "path""/api/resourceNotFoundException3" 

ResponseStatusException 提供了三个构造方法:

  1. public ResponseStatusException(HttpStatus status) { 
  2.  this(status, nullnull); 
  3.  } 
  4.  public ResponseStatusException(HttpStatus status, @Nullable String reason) { 
  5.  this(status, reason, null); 
  6.  } 
  7.  public ResponseStatusException(HttpStatus status, @Nullable String reason, @Nullable Throwable cause) { 
  8.  super(null, cause); 
  9.  Assert.notNull(status, "HttpStatus is required"); 
  10.  this.status = status; 
  11.  this.reason = reason; 
  12.  } 

构造函数中的参数解释如下:

•status :http status

•reason :response 的消息内容

•cause :抛出的异常

由于Python语言的简洁性、易读性以及可扩展性,在国外用Python做科学计算的研究机构日益增多,一些知名大学已经采用Python来教授程序设计课程。

 

赞(28)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程