下面就来详细讲解“SpringBoot如何优雅地处理全局异常”的完整攻略。
知识前置
在正式进入如何优雅地处理全局异常之前,我们需要先了解一些相关的知识。
异常分类
在Java中,异常分为两种:
- 可检查异常(checked exception):这种异常在编译期就能检查出来。
- 不可检查异常(unchecked exception):这种异常通常是由于程序内部错误引起的,比如空指针异常、数组越界异常等等。
异常处理
在Java中,我们可以通过以下三种方式来处理异常:
- 捕获异常:使用try-catch语句来捕获异常。
- 声明异常:在方法签名上声明方法可能会抛出的异常。
- 抛出异常:在方法中使用throw语句来抛出异常。
SpringBoot异常处理
SpringBoot中提供了一个异常处理机制,可以自定义全局异常处理器,来处理应用程序中的异常。如果没有配置全局异常处理器,则SpringBoot会采用默认的异常处理器来处理异常。
在SpringBoot中,我们需要定义一个异常处理类并实现ErrorController接口或者使用@ControllerAdvice注解来处理全局异常。
实现全局异常处理
下面我们就来看看如何实现全局异常处理。
实现ErrorController接口
实现ErrorController接口的步骤如下:
- 创建一个异常处理类,比如说我们可以取名为GlobalExceptionHandler。
- 在GlobalExceptionHandler类中,实现ErrorController接口,并定义error()方法。
- 在error()方法中,判断异常类型,并返回自定义的异常响应信息。
代码示例:
@RestControllerAdvice
public class GlobalExceptionHandler implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
@ExceptionHandler(value = Exception.class)
public ApiResponse<String> handleException(Exception e) {
if (e instanceof BusinessException) {
BusinessException businessException = (BusinessException) e;
return ApiResponse.fail(businessException.getCode(), businessException.getMessage());
} else {
return ApiResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器异常,请稍后再试!");
}
}
@RequestMapping("/error")
public ApiResponse<String> error(HttpServletRequest request) {
Integer code = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (code == null) {
return ApiResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器异常,请稍后再试!");
}
return ApiResponse.fail(code, "服务器异常,请稍后再试!");
}
}
上面的代码中,我们使用@RestControllerAdvice注解来代替@ControllerAdvice注解,这样就可以省略在每个方法上都添加@ResponseBody注解的步骤了。
在handleException()方法中,我们使用@ExceptionHandler注解来指定要处理的异常类型。如果发生了BusinessException,则返回自定义的异常响应信息;否则返回“服务器异常,请稍后再试!”这样的默认异常信息。同时,我们还需要重写getErrorPath()方法来指定错误处理的路径为“/error”。
在error()方法中,我们通过HttpServletRequest对象获取异常状态码,并返回自定义的异常响应信息。
使用@ControllerAdvice注解
使用@ControllerAdvice注解的步骤如下:
- 创建一个异常处理类,比如说我们可以取名为GlobalExceptionHandler。
- 在GlobalExceptionHandler类中,添加@ControllerAdvice注解。
- 在GlobalExceptionHandler类中,添加@ExceptionHandler注解来处理异常,并返回自定义的异常响应信息。
代码示例:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ApiResponse<String> handleException(Exception e) {
if (e instanceof BusinessException) {
BusinessException businessException = (BusinessException) e;
return ApiResponse.fail(businessException.getCode(), businessException.getMessage());
} else {
return ApiResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器异常,请稍后再试!");
}
}
}
上面的代码中,我们使用@RestControllerAdvice注解来代替@ControllerAdvice注解,这样就可以省略在每个方法上都添加@ResponseBody注解的步骤了。
在handleException()方法中,我们使用@ExceptionHandler注解来指定要处理的异常类型。如果发生了BusinessException,则返回自定义的异常响应信息;否则返回“服务器异常,请稍后再试!”这样的默认异常信息。
示例说明
下面我们通过两个示例来说明如何优雅地处理全局异常。
示例1:处理NullPointerException异常
假设我们有一段代码如下:
@RequestMapping("/test")
public ApiResponse<String> test() {
String str = null;
str.startsWith("a");
return ApiResponse.success();
}
当我们访问“/test”接口时,程序就会抛出NullPointerException异常。为了避免这个异常对用户造成困扰,我们可以在GlobalExceptionHandler中定义异常处理方法如下:
@ResponseBody
@ExceptionHandler(NullPointerException.class)
public ApiResponse<String> handleNullPointerException(NullPointerException e) {
return ApiResponse.fail("服务器异常,请稍后再试!");
}
这样,当程序抛出NullPointerException异常时,就会返回自定义的异常响应信息。
示例2:处理自定义异常
假设我们的应用程序中有一个自定义的异常类叫做“BusinessException”,该异常类有两个属性:异常代码和异常信息。当我们在程序中需要抛出该异常时,可以这样做:
throw new BusinessException(1001, "该用户不存在!");
为了将自定义的异常转换为可供客户端展示的异常信息,我们可以在GlobalExceptionHandler中定义异常处理方法如下:
@ResponseBody
@ExceptionHandler(BusinessException.class)
public ApiResponse<String> handleBusinessException(BusinessException e) {
return ApiResponse.fail(e.getCode(), e.getMessage());
}
这样,当程序抛出BusinessException异常时,就会返回该异常包含的异常代码和异常信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot如何优雅地处理全局异常详解 - Python技术站