如何在Spring中找到匹配指定URI的RestController模板?
一、先搞懂Spring MVC的URI匹配逻辑
Spring MVC会把所有@RequestMapping(包括@GetMapping、@PostMapping这些简化注解)的模板解析成RequestMappingInfo对象,里面存着URI模板、请求方法、参数这些匹配条件。当请求进来时,DispatcherServlet会挨个遍历这些对象,按优先级匹配:
- 优先匹配精确路径:比如如果有个接口直接写了
/users/1,那肯定先命中这个,轮不到/users/{id} - 没精确匹配的话,再找带占位符的模板:像
/users/{id}这种,能匹配/users/1、/users/abc这类结构一致的路径 - 通配符匹配(比如
/users/*、/**)优先级最低,只有前面都没匹配上才会考虑
二、实际开发里的几种定位方法
1. 用Spring Boot Actuator(项目加了这个依赖的话)
如果项目引了Actuator,直接访问/actuator/mappings端点,就能看到所有注册的请求映射。你可以搜输入的URI,或者找结构能对上的模板,比如搜/users/1,就能找到对应的/users/{id}模板,还能看到对应的Controller类和方法。
2. 开DEBUG日志看匹配过程
给org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping这个类开DEBUG级别的日志,请求进来时,日志会详细输出匹配过程:哪些映射被检查了,最终选中了哪一个。这样一眼就能看到/users/1是匹配到/users/{id}的。
3. 手动搜(小项目适用)
直接全局搜项目里的@GetMapping、@PostMapping这些注解,把所有URI模板收集起来,自己按Spring的规则比对:先看有没有一模一样的路径,没有的话就看带占位符的,比如把/users/1最后一段换成{id},看看有没有对应的模板;或者看模板里的占位符位置和输入URI的结构对不对得上。
4. 代码里动态获取匹配结果
如果需要在代码里自动找,可以注入RequestMappingHandlerMapping,然后用它的方法来判断:
@Autowired private RequestMappingHandlerMapping handlerMapping; public String findMatchingTemplate(String requestUri) { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI(requestUri); request.setMethod(HttpMethod.GET.name()); // 根据实际请求方法调整 try { HandlerExecutionChain chain = handlerMapping.getHandler(request); if (chain != null) { HandlerMethod handlerMethod = (HandlerMethod) chain.getHandler(); RequestMappingInfo mappingInfo = handlerMapping.getMappingForMethod(handlerMethod.getMethod(), handlerMethod.getBeanType()); return mappingInfo.getPatternsCondition().getPatterns().iterator().next(); } } catch (Exception e) { e.printStackTrace(); } return null; }
这段代码用Mock请求模拟输入的URI,然后通过RequestMappingHandlerMapping找到对应的映射信息,提取出URI模板。
内容的提问来源于stack exchange,提问作者CaptainDaVinci

