如何获取Spring Boot所有请求映射(含参数、响应类型)
如何获取Spring Boot全量请求映射(含控制器、过滤器、框架端点)
1. 最优方案:复用Actuator的映射收集逻辑
Spring Boot Actuator的MappingsEndpoint已经封装了所有类型请求映射的收集逻辑,直接复用它就能拿到和/actuator/mappings一致的全量数据,包含参数类型、响应类型、处理器信息等细节。
代码示例
import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; import org.springframework.stereotype.Component; @Component public class MappingCollector { private final MappingsEndpoint mappingsEndpoint; public MappingCollector(MappingsEndpoint mappingsEndpoint) { this.mappingsEndpoint = mappingsEndpoint; } public void collectAllMappings() { var allMappings = mappingsEndpoint.mappings(); // 收集控制器映射(含参数、响应类型) allMappings.getRequestMappingMappings().forEach(mapping -> { System.out.println("控制器路径: " + mapping.getPatterns()); System.out.println("请求方法: " + mapping.getMethods()); System.out.println("参数类型: " + mapping.getParameters()); System.out.println("响应类型: " + mapping.getProduces()); System.out.println("处理方法: " + mapping.getHandler()); System.out.println("---"); }); // 收集Actuator端点映射 allMappings.getMvcEndpointMappings().forEach(mapping -> { System.out.println("Actuator端点路径: " + mapping.getPatterns()); System.out.println("处理类: " + mapping.getHandler()); System.out.println("---"); }); // 收集过滤器映射 allMappings.getFilterMappings().forEach(mapping -> { System.out.println("过滤器路径: " + mapping.getUrlPatterns()); System.out.println("过滤器类: " + mapping.getFilterName()); System.out.println("---"); }); // 收集框架自带映射(如静态资源) allMappings.getHandlerMappings().forEach(mapping -> { if ("SimpleUrlHandlerMapping".equals(mapping.getHandlerMappingBeanName())) { mapping.getMappings().forEach((path, handler) -> { System.out.println("静态资源路径: " + path); System.out.println("处理器: " + handler); System.out.println("---"); }); } }); } }
2. 无Actuator依赖:手动收集各类映射
如果不想引入Actuator依赖,可以分别收集不同类型的映射:
2.1 收集控制器映射(含参数、响应类型)
通过RequestMappingHandlerMapping获取控制器方法的详细信息,解析参数和响应类型:
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.method.HandlerMethod; import org.springframework.core.GenericTypeResolver; import java.util.Arrays; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; // 在组件类中注入HandlerMapping列表 @Autowired private List<org.springframework.web.servlet.HandlerMapping> handlerMappings; public void collectControllerMappings() { for (org.springframework.web.servlet.HandlerMapping hm : handlerMappings) { if (hm instanceof RequestMappingHandlerMapping rmhm) { rmhm.getHandlerMethods().forEach((info, method) -> { // 请求路径与方法 System.out.println("路径: " + info.getPatternsCondition().getPatterns()); System.out.println("请求方法: " + info.getMethodsCondition().getMethods()); // 参数类型 Class<?>[] paramTypes = method.getMethod().getParameterTypes(); System.out.println("参数类型: " + Arrays.toString(paramTypes)); // 响应类型(解析泛型) Type resolvedReturnType = GenericTypeResolver.resolveReturnType(method.getMethod(), method.getBeanType()); System.out.println("响应类型: " + resolvedReturnType.getTypeName()); System.out.println("---"); }); } } }
2.2 收集过滤器映射
注入FilterRegistrationBean列表,获取每个过滤器的匹配路径:
import org.springframework.boot.web.servlet.FilterRegistrationBean; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @Autowired private List<FilterRegistrationBean<?>> filterRegistrations; public void collectFilterMappings() { filterRegistrations.forEach(frb -> { System.out.println("过滤器类: " + frb.getFilter().getClass().getName()); System.out.println("匹配路径: " + frb.getUrlPatterns()); System.out.println("执行顺序: " + frb.getOrder()); System.out.println("---"); }); }
2.3 收集框架自带映射
筛选SimpleUrlHandlerMapping获取静态资源映射,筛选AbstractWebMvcEndpointHandlerMapping获取Actuator端点映射:
public void collectFrameworkMappings() { for (org.springframework.web.servlet.HandlerMapping hm : handlerMappings) { // 静态资源映射 if (hm instanceof org.springframework.web.servlet.handler.SimpleUrlHandlerMapping suhm) { suhm.getUrlMap().forEach((path, handler) -> { if (handler instanceof org.springframework.web.servlet.resource.ResourceHttpRequestHandler) { System.out.println("静态资源路径: " + path); System.out.println("处理器: " + handler.getClass().getName()); System.out.println("---"); } }); } // Actuator端点映射 else if (hm instanceof org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping awhm) { awhm.getHandlerMethods().forEach((info, method) -> { System.out.println("Actuator端点路径: " + info.getPatternsCondition().getPatterns()); System.out.println("处理方法: " + method.getMethod().getName()); System.out.println("---"); }); } } }
3. 注意事项
- 复用Actuator逻辑时,需确保项目引入
spring-boot-starter-actuator依赖; - 手动收集时,
HandlerMapping的实现类可能随Spring Boot版本略有差异,需根据实际版本调整; - 泛型响应类型需用
GenericTypeResolver解析,才能拿到真实的泛型参数类型。
内容的提问来源于stack exchange,提问作者EchoCow
相关产品推荐
相关产品推荐

