SpringBoot中实现全局异常处理,统一返回错误信息给前端

背景引入 :最近实现了一个限流切面类,但是在限流方法中throw异常,会直接打印到控制台,报错500,对前端很不友好。因为是注解,又没办法捕获再处理。那么怎么才能将错误码返回给前端呢?原来是全局异常处理......

切面方法:

java 复制代码
@Before(value = "AccessLimitPointcut()")
    public void handleAccessLimit(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RateLimiter annotation = AnnotationUtils.findAnnotation(method, RateLimiter.class);
        int accessMaxTimes = annotation.count();
        long timeOut = annotation.time();
        TimeUnit timeUnit = annotation.timeUnit();
        String key = annotation.key();
        // 如果redis不存在或已经过期
        Long expire = redisTemplate.opsForValue().getOperations().getExpire(key);
        if (!redisTemplate.hasKey(key) || Objects.requireNonNull(expire).intValue() < 0) {
            redisTemplate.opsForValue().set(key, 1, timeOut, timeUnit);
        } else {
            long increment = redisTemplate.opsForValue().increment(key).intValue();
            if (increment > accessMaxTimes) {
                throw new AIDocException("PA-COM-000001", "访问已经超过最大值: " + accessMaxTimes);
            }
        }
    }

如果没有引入全局异常处理,那么异常会直接展示在控制台

如何实现:用@RestControllerAdvice和@ExceptionHandler注解在SpringBoot中实现全局异常处理

1、@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。

2、@RestControllerAdvice 是组件注解,他使得其实现类能够被classpath扫描自动发现,如果应用是通过MVC命令空间或MVC Java编程方式配置,那么该特性默认是自动开启的。

java 复制代码
@RestControllerAdvice
public class AIDocExceptionHandler {
	
	private Logger logger = LoggerFactory.getLogger(AIDocExceptionHandler.class);

	/**
	 * 处理自定义异常
	 */
	@ExceptionHandler(Exception.class)
	@ResponseBody
	public Map<String, Object> handleRRException(Exception e) {
		Map<String, Object> map = new HashMap<>();
		if (e instanceof AIDocException) {
			map.put("code",((AIDocException) e).getCode());
			map.put("msg", ((AIDocException) e).getMsg());
		}else {
			logger.error("【系统异常】{}", e);
			map.put("code", ErrorConstants.INVOKE_FAIL);
			map.put("msg","未知异常!");
		}
		return map;
	}
}

其中AIDocException是自定义异常类,你可以根据你的需求编写自己的自定义异常类。

以上就实现了全局统一异常管理,是不是很简单?

相关推荐
YIAN13 分钟前
从手写 Agent 工具到 MCP 协议:一文搞懂大模型跨进程跨语言工具调用
后端·agent·mcp
小兔崽子去哪了39 分钟前
Docker 删除镜像后磁盘空间没有释放?
后端·docker·容器
凤凰院凶涛QAQ1 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
高明珠1 小时前
麒麟 V10 SP1 排查实录:ttyS5 每 10 秒莫名收到一批报文,元凶是 eGTouchD
后端
卷无止境1 小时前
Python FFI 技术深度解析:ctypes、cffi 与 pybind11 的性能差异与实践挑战
后端·python
ServBay1 小时前
AI Gateway 是什么?为什么每个平台都在做
后端·aigc·ai编程
SamDeepThinking2 小时前
Vibe Coding最重要的是Spec
后端·程序员·ai编程
掘金_答案2 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构
妙码生花2 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十三):权限规则管理器
后端·go·gin
猿与禅2 小时前
CosId 分布式 ID 生成器完全教程:从架构原理到生产落地
java·shardingsphere·雪花算法·分布式id·高性能·cosid·号段模式