沉思获得匹配特定的URL Spring MVC控制器列表(Reflectively getting

2019-08-04 15:22发布

如何反思获取所有控制器的列表(最好的,如果不仅是注释,但在XML中也规定),匹配在Spring MVC应用程序的一些specfic网址是什么?

在注释只的情况下,

@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配置指定控制器? 而如何处理请求的路径参数?

Answer 1:

由于弹簧3.1,有类RequestMappingHandlerMapping ,它提供关于映射(信息RequestMappingInfo @Controller类)。

@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是在其中控制器被限定的弹簧上下文中定义。



Answer 2:

您可以通过调用得到一个映射控制器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所有控制器。 这将geht你只有一个完全匹配的控制器。 这显然不希望你的需要。



Answer 3:

您可以尝试使用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的豆类访问这个网页,看看如何可以做。



Answer 4:

你需要做的RequestMappingHandlerMapping一个条目的调度的servlet

<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;

它应该很好地工作。

注意:您需要采取加豆的照顾,如果你的任何的DispatcherServlet(在大的应用程序的情况下)的包含这个bean会导致成noUniqueBean例外和应用无法启动。



文章来源: Reflectively getting list of Spring MVC controllers matching specific url