反射性地获取与特定 url 匹配的 Spring MVC 控制器列表

2022-09-02 19:57:06

如何反射性地获取所有控制器的列表(最好是不仅带注释,而且还以xml指定),匹配Spring MVC应用程序中的一些特定URL?

如果是仅带注释的,

@Autowired
private ListableBeanFactory listableBeanFactory;
...
whatever() {
    Map<String,Object> beans = listableBeanFactory.getBeansWithAnnotation(RequestMapping.class);

    // iterate beans and compare RequestMapping.value() annotation parameters
    // to produce list of matching controllers
}

可以使用,但是在更一般的情况下该怎么办,当控制器可以在spring中指定时.xml配置?如何处理请求路径参数?


答案 1

从Spring 3.1开始,出现了类 RequestMappingHandlerMapping,它提供了有关@Controller类的映射(RequestMappingInfo)的信息。

@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;

@PostConstruct
public void init() {
    Map<RequestMappingInfo, HandlerMethod> handlerMethods =
                              this.requestMappingHandlerMapping.getHandlerMethods();

    for(Entry<RequestMappingInfo, HandlerMethod> item : handlerMethods.entrySet()) {
        RequestMappingInfo mapping = item.getKey();
        HandlerMethod method = item.getValue();

        for (String urlPattern : mapping.getPatternsCondition().getPatterns()) {
            System.out.println(
                 method.getBeanType().getName() + "#" + method.getMethod().getName() +
                 " <-- " + urlPattern);

            if (urlPattern.equals("some specific url")) {
               //add to list of matching METHODS
            }
        }
    }       
}

重要的是,在定义控制器的弹簧上下文中定义此bean。


答案 2

您可以通过调用 来获得映射的控制器。IoC 可以获取处理程序映射实例。如果您没有HTTPServletRequest,则可以使用MockHttpServletRequest构建您的请求。HandlerMapping.getHandler(HTTPServletRequest).getHandler()

@Autowired
private HandlerMapping mapping;

public Object getController(String uri) {
    MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
    // configure your request to some mapping
    HandlerExecutionChain chain = mapping.getHandler(request);
    return chain.getHandler();
}

抱歉,我现在读到您希望所有控制器都使用 URL。这将只给你一个完全匹配的控制器。这显然不是你想要的。