目录
一、springboot中处理异常的方式?
1、try....catch处理异常
如果采用这种方式,虽然可以解决,但是存在弊端,需要我们在保存其他业务数据时,也需要在其他方法中加上try…catch进行处理,代码冗余,不通用。
代码可读性:业务逻辑代码中混入大量的异常处理代码会降低代码的可读性,使得主要业务逻辑变得难以理解和维护。
代码可维护性:如果在每个可能抛出异常的地方都使用
try...catch
,将使得代码变得冗长和复杂,增加维护成本。异常的传播:异常的目的是传递错误信息,如果每个地方都捕获并处理异常,可能会隐藏错误的根本原因,使得问题难以被发现和解决。
2、全局异常处理器
Spring Boot的全局异常处理是通过@ControllerAdvice
或@RestControllerAdvice
注解的类来实现的。这些类可以捕获和处理应用程序中的异常,并返回统一的错误响应。
二、为什么需要全局异常处理?
- 统一错误响应:全局异常处理允许你定义一个统一的错误响应格式,这样无论在应用程序的哪个部分发生异常,都能返回一致的错误信息。这有助于前端开发者更好地处理错误,提升用户体验。
- 避免代码重复:如果没有全局异常处理,你可能需要在每个控制器或服务中重复编写异常处理代码。全局异常处理机制可以集中处理异常,减少代码重复,提高代码的可维护性。
- 增强可维护性:集中管理异常处理逻辑使得代码更加模块化,易于维护和更新。当需要修改错误处理逻辑时,你只需要在一个地方进行修改,而不需要逐个修改每个控制器或服务。
- 提高系统的健壮性:全局异常处理可以捕获并处理那些在应用程序运行过程中可能未被预期到的异常。这有助于避免应用程序因未处理的异常而崩溃,增强了系统的健壮性。
- 日志记录和监控:全局异常处理通常伴随着日志记录,这有助于开发者在开发和生产环境中监控和诊断问题。通过记录详细的错误信息和堆栈跟踪,可以快速定位问题并进行修复。
- 安全性”通过全局异常处理,可以避免将敏感的系统信息(如内部错误代码或堆栈跟踪)暴露给用户。你可以自定义错误信息,只向用户显示必要的错误详情,从而提高系统的安全性。
- 符合RESTful API设计原则:在RESTful API设计中,使用HTTP状态码来表示不同的错误类型是一种常见的做法。全局异常处理可以帮助你根据异常类型自动设置合适的HTTP状态码,符合RESTful API的设计原则。
- 减少客户端处理复杂性:当客户端(如移动应用或前端应用)调用后端服务时,全局异常处理可以确保返回一个清晰、一致的错误格式。这使得客户端开发者更容易理解和处理这些错误,减少客户端代码的复杂性。
三、全局异常处理实现
全局异常处理类
package com.example.demo.exception;
import com.example.demo.response.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalException {
@ExceptionHandler(value = {Exception.class})
public Result<String> ex(Exception e)
{
return Result.error(e.getMessage());
}
}
controller类
@GetMapping("test")
public int test(){
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 10; i++){
integers.add(i);
}
//故意数组过界
for (int i = 0; i < 20; i++){
System.out.println(integers.get(i));
}
return 1;
}
result结果类
package com.example.demo.response;
import lombok.Data;
@Data
public class Result<T> {
private int code;
private String msg;
private T data;
public Result() {
}
public Result(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static Result<String> error(String message) {
return new Result(500, message, null);
}
}
四、测试
我下面使用到的工具是apifox,当然你也可以直接使用postman或者浏览器测试。
启动springboot项目
使用apifox发送请求,请求结果如下所示:
这个地方我们就可以发现实际上就是自动的帮我们做了异常处理了,当然我给的这个实例只是针对于全部的异常而不是自定义的异常。
五、@ControllerAdvice详解
@ControllerAdvice
是 Spring MVC 提供的一个注解,用于定义一个类作为全局异常处理器。使用这个注解的类可以捕获和处理来自 Spring MVC 控制器的异常。
以下是 @ControllerAdvice
注解的一些关键点:
- 作用域:通常用于处理
@Controller
或@RestController
中抛出的异常。 - 方法:在类中定义的方法可以使用
@ExceptionHandler
注解来指定处理特定类型的异常。 - 返回类型:处理方法通常返回
ModelAndView
或ResponseEntity
对象,以便控制视图和响应状态。
当然@ControllerAdvice也是可以设置参数的,可以设置不是作用于全部的controller下,具体实例如下所示:
@RestControllerAdvice(annotations = {RestController.class})
@ControllerAdvice(annotations = {RestController.class, Controller.class})
六、@ExceptionHandler 详解
1.用法:
- @ExceptionHandler 注解可以用于方法级别,用于标记一个方法为异常处理方法。
- 异常处理方法需要定义在控制器类中,并且可以有任意的访问修饰符。
2.参数:
- 异常处理方法的参数可以是异常类型,也可以是其他类型的参数。
- 如果异常处理方法的参数是异常类型,则该方法只会处理指定类型的异常。
- 如果异常处理方法的参数是其他类型的参数,则该方法会处理所有类型的异常,并且异常对象会作为参数传递给方法。
3.异常处理逻辑:
- 异常处理方法可以编写任意的异常处理逻辑,比如记录日志、返回错误信息、执行特定的补救措施等。
- 在方法中可以通过异常对象来获取异常信息,如异常消息、堆栈轨迹等。
4.多个异常处理方法:
- 一个控制器类可以有多个异常处理方法,用来处理不同类型的异常。
- 当多个异常处理方法都能处理同一类型的异常时,Spring 框架会选择最匹配的异常处理方法来处理异常。