Spring注解之@ExceptionHandler 统一异常处理和获取方法名

摘要:在 Spring Boot 中,使用Spring注解@ControllerAdvice 和 @ExceptionHandler 统一处理异常,并捕获方法名,从而快速定位错误原因。

背景分析

  最近走查线上环境日志时,发现打印了很多org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported异常日志,虽然知道是因为接口不支持GET请求导致的,但是,定位不到是因为错误调用哪个接口导致,给人很大困惑。

@ExceptionHandler介绍

  异常处理器@ExceptionHandler是Spring MVC框架中用于处理异常的注解,方法名按需自定义,方法参数可以是Exception及其子类对象、HttpServletRequest、HttpServletResponse等,系统会自动为它们赋值。方法返回值类型可以为ModelAndView、Model、Map、View、String以及void等。它的作用是把各个Controller中抛出的异常集中到一个类中处理。

  在被@ControllerAdvice或者@RestControllerAdvice修饰的类里,可以使用@ExceptionHandler捕捉异常,返回值类型为Map的示例如下:

java 复制代码
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {
	/*
   * 捕捉HTTP请求方式异常HttpRequestMethodNotSupportedException
   */
   @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
   public Map<String, Object> handleBadMethodException(HttpRequestMethodNotSupportedException exception, HttpServletRequest req) {
       log.error("不支持的请求方式:{}-{}", req.getRequestURI(), exception.getMessage());
       Map<String, Object> result=new HashMap();
       result.put("msg","不支持的请求方式");
       result.put("code", HttpStatus.METHOD_NOT_ALLOWED.value());
       return result;
   }
}

  @RestControllerAdvice:放在类的上面,表示这个类中有异常处理器,它是基于AOP的、对控制器类的一个增强。

  req.getRequestURI()用于获取当前API访问路径的URI,里面包含方法名,用于快速定位是哪个API出错。

  在上述异常处理器示例中,当控制层抛出HttpRequestMethodNotSupportedException异常时,handleBadMethodException方法会被调用,返回一个包含错误信息的Map对象。如果把@ExceptionHandler(HttpRequestMethodNotSupportedException.class)改为@ExceptionHandler(Exception.class),则是处理全局异常了,会捕获所有未被其它方法处理的异常,这样处理的缺点是异常太过宽泛,不利于排查问题。

  验证功能的方法很简单,请使用GET请求访问仅支持POST请求的函数,此时,控制台将打印如下信息:

不支持的请求方式:/wiener/XXXMethod-Request method 'GET' not supported

结束语

  Spring MVC的@ExceptionHandler注解为Web应用程序提供了便捷的异常处理机制。通过使用该注解,可以在控制器中捕获和处理特定类型的异常,提供友好的错误信息给用户。在实际项目中,合理使用@ExceptionHandler能够提高代码的可维护性和用户体验。通过本文的解析和实践,读者可以更好地理解和掌握@ExceptionHandler的用法和原理。希望这篇文章对您有所帮助,感谢阅读!

相关推荐
一 乐7 小时前
高校实习信息发布网站|基于Spring Boot的高校实习信息发布网站的设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·高校实习信息发布网站
han_hanker8 小时前
BeanUtils.copyProperties 和序列化的问题
java·开发语言·spring boot
西凉的悲伤9 小时前
Spring Boot 中 @Async(value = “alertThreadPool“) 是什么?为什么企业项目喜欢自定义线程池?
spring boot·多线程·async·异步
闪电悠米10 小时前
黑马点评-优惠券秒杀-05_local_lock_cluster_problem
java·spring boot·redis·缓存
小江的记录本11 小时前
【JVM虚拟机】类加载机制:类加载全流程:加载→验证→准备→解析→初始化(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·算法·安全·spring·面试
搬石头的马农11 小时前
Claude Code SpringBoot开发:从0到1搭建企业级项目的6个核心Skill
java·人工智能·spring boot·后端·ai编程
yurenpai(27届找实习中)12 小时前
redis_点评(26.附近店铺——实现附近商家功能)
数据库·spring boot·redis
愤怒的苹果ext13 小时前
Spring Boot Redis Stream队列
spring boot·redis·消息队列·stream
小江的记录本13 小时前
【Spring AI】Spring AI中RAG误触发与系统提示词泄露问题解决方案(完整版+代码方案)
java·人工智能·spring boot·后端·python·spring·面试
过期动态13 小时前
【LeetCode 热题 100】无重复字符的最长子串
java·数据结构·spring boot·算法·leetcode·职场和发展