全局异常处理
716字约2分钟
2024-08-08
实战内容请移步 全局异常处理实战
为何需要全局异常处理?
开发过程中,难免有的程序会因为某些原因抛出异常,而这些异常一般都是利用 try catch
的方式处理异常或者 throw
、throws
的方式抛出异常不管。这种方法对于程序员来说处理也比较麻烦,对客户来说也不太友好,所以我们希望既能方便程序员编写代码,不用过多的自己去处理各种异常编写重复的代码又能提升用户的体验,这时候全局异常处理就显得很重要也很便捷了。
@ControllerAdvice
@ControllerAdvice
是 Spring 3.2
提供的新注解,学名是 Controller
增强器,作用是给 Controller
控制器添加统一的操作或处理。
@ControllerAdvice
是在类上声明的注解,其用法主要有三点:
1、结合方法型注解
@ExceptionHandler
,用于捕获Controller
中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的。2、结合方法型注解
@InitBinder
,用于request
中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的。3、结合方法型注解
@ModelAttribute
,表示其注解的方法将会在目标Controller
方法执行之前执行。
在启动应用之后,被 @ExceptionHandler
、 @InitBinder
和 @ModelAttribute
注解的方法都会作用在被 @RequestMappping
注解的方法上。
@ControllerAdvice
的用法基本是将其声明在某个bean
上,然后在该bean
的方法上使用其他的注解来指定不同的织入逻辑。不过这里@ControllerAdvice
并不是使用AOP
的方式来织入业务逻辑的,而是Spring
内置对其各个逻辑的织入方式进行了内置支持。
栗子
依赖引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
统一异常处理器
ResultDTO
是封装的通用结果类,详解请移步 封装通用结果类
package com.marui.exception.handle.common.exception;
import com.marui.exception.handle.common.ResultDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @ClassName AppExceptionHandler
* @Desciption 全局统一异常处理器
* @Author MaRui
* @Date 2023/2/24 11:01
* @Version 1.0
*/
@RestControllerAdvice
public class AppExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@ExceptionHandler(Exception.class)
public ResultDTO handleException(Exception e) {
logger.error(e.getMessage(), e);
return ResultDTO.error("500", "未知错误,请联系系统管理员");
}
}
Controller 测试代码
/**
* @ClassName MessageController
* @Desciption 消息控制层
* @Author MaRui
* @Date 2023/2/24 11:08
* @Version 1.0
*/
@Data
@RestController
@RequestMapping(value = "/message")
public class MessageController {
@GetMapping(value = "/getMessage")
public ResultDTO getMessage() {
int a = 1/0;
return ResultDTO.ok();
}
}