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



如何反射地获得所有控制器的列表(最好不仅有注释,而且在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配置中指定时,该怎么办呢?如何处理请求路径参数?

从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
            }
        }
    }       
}

在定义控制器的spring上下文中定义这个bean是很重要的。

通过调用HandlerMapping.getHandler(HTTPServletRequest).getHandler()获得映射的控制器。HandlerMapping实例可以由IoC获得。如果你没有HTTPServletRequest,你可以使用MockHttpServletRequest构建请求。

@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的所有控制器。这将只获得一个完全匹配的控制器。这显然不是你想要的

您可以尝试使用ListableBeanFactory接口来检索所有bean名称。

private @Autowired ListableBeanFactory beanFactory;
public void doStuff() {
    for (String beanName : beanFactory.getBeanDefinitionNames()) {
        if (beanName.startsWith("env")) { // or whatever check you want to do
            Object bean = beanFactory.getBean(beanName)
            // .. do something with it
        }
    }
}

在这里查看ListableBeanFactory的文档。该接口提供了getBeansOfType()、getBeanDefinitionCount()等方法

如果这种方法没有列出@Controller注释的bean,请访问该页以查看如何做到这一点。

您需要在dispatcher servlet中为RequestMappingHandlerMapping做一个条目

<bean name="requestHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="useTrailingSlashMatch" value="true"></property>
    </bean>

分派器servlet将查看此映射并在您的应用程序中实例化bean RequestMappingHandlerMapping

现在在任何控制器/类中你都可以使用

@Autowired
private HandlerMapping mapping;

,它应该可以正常工作。

注意:你需要注意添加bean,如果你的任何dispatcherservlet(在大型应用程序的情况下)包含这个bean,它将导致一个noUniqueBean异常和应用程序无法启动。

相关内容

  • 没有找到相关文章

最新更新