如何在HandlerInterceptor中获取Controller完整@RequestMapping路径
获取Spring控制器完整请求映射路径(含类与方法级别)
要在拦截器中获取包含类级别@RequestMapping的完整路径模板(如/v4/base/users/{userId}),而非仅方法级路径或带实际参数的请求路径,可通过以下两种可靠方式实现:
方法一:手动拼接类与方法的映射路径
直接从HandlerMethod中提取类和方法上的映射注解,手动拼接路径,同时兼容@PostMapping/@GetMapping等派生注解:
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException { if (!(handler instanceof HandlerMethod handlerMethod)) { return true; } // 提取类级别@RequestMapping路径 String classPath = ""; RequestMapping classMapping = handlerMethod.getBeanType().getAnnotation(RequestMapping.class); if (classMapping != null && classMapping.path().length > 0) { classPath = classMapping.path()[0]; } // 提取方法级别映射路径(兼容派生注解) String methodPath = ""; RequestMapping methodMapping = handlerMethod.getMethodAnnotation(RequestMapping.class); // 处理@PostMapping if (methodMapping == null) { PostMapping postMapping = handlerMethod.getMethodAnnotation(PostMapping.class); if (postMapping != null) { methodPath = postMapping.path().length > 0 ? postMapping.path()[0] : postMapping.value()[0]; } } // 可扩展处理@GetMapping/@PutMapping等其他注解 else { methodPath = methodMapping.path().length > 0 ? methodMapping.path()[0] : methodMapping.value()[0]; } // 拼接完整路径,处理斜杠重复问题 String fullPath = classPath + (methodPath.startsWith("/") ? methodPath : "/" + methodPath); // fullPath即为目标路径模板:/v4/base/users/{userId} System.out.println(fullPath); return true; } }
方法二:利用Spring内置的RequestMappingHandlerMapping(推荐)
通过注入RequestMappingHandlerMapping,直接获取Spring已解析完成的完整RequestMappingInfo,无需手动拼接:
@Component public class MyInterceptor implements HandlerInterceptor { private final RequestMappingHandlerMapping requestMappingHandlerMapping; // 构造注入Spring容器中的RequestMappingHandlerMapping实例 public MyInterceptor(RequestMappingHandlerMapping requestMappingHandlerMapping) { this.requestMappingHandlerMapping = requestMappingHandlerMapping; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException { if (!(handler instanceof HandlerMethod handlerMethod)) { return true; } try { // 获取已解析的完整映射信息 RequestMappingInfo mappingInfo = requestMappingHandlerMapping.getMappingForMethod( handlerMethod.getMethod(), handlerMethod.getBeanType() ); if (mappingInfo != null) { // 提取路径模板(通常集合中只有一个路径) Set<String> pathPatterns = mappingInfo.getPathPatternsCondition().getPatternValues(); String fullPath = pathPatterns.iterator().next(); // 输出结果:/v4/base/users/{userId} System.out.println(fullPath); } } catch (Exception e) { e.printStackTrace(); } return true; } }
关键注意事项
- 仅当
handler类型为HandlerMethod时,才是Spring控制器的方法请求,需先做类型判断 - 方法二更可靠,Spring已自动处理类与方法路径的拼接、派生注解解析、路径规则兼容等逻辑
- 避免使用
request.getServletPath(),它返回的是包含实际参数值的请求路径(如/v4/base/users/23232),不符合需求
内容的提问来源于stack exchange,提问作者Sumama Waheed
相关产品推荐
相关产品推荐

