Подтвердить что ты не робот

Отражающий получение списка Spring контроллеров MVC, соответствующих определенному URL-адресу

Как отразить список всех контроллеров (лучше всего, если не только аннотировать, но также указать в xml), сопоставляя некоторый specfic url в вашем приложении Spring MVC?

В случае только аннотированных

@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 config? А что делать с параметрами запроса-пути?

4b9b3361

Ответ 1

Так как Spring 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 был определен в контексте Spring, где определены контроллеры.

Ответ 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-адреса. Это даст вам только один точно подобранный контроллер. Это явно не хочет, чтобы вам нужно.

Ответ 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 аннотированную beans эту страницу, чтобы увидеть, как это можно сделать.

Ответ 4

вам нужно сделать запись для RequestMappingHandlerMapping в сервлет вашего диспетчера

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

сервлет диспетчера будет изучать это сопоставление и создавать экземпляр bean RequestMappingHandlerMapping в вашем приложении

теперь в любом из вашего контроллера/класса вы можете использовать

@Autowired
private HandlerMapping mapping;

и он должен работать нормально.

Примечание: вам нужно позаботиться о добавлении bean, если какой-либо из вашего диспетчера (в случае большого приложения) содержит этот bean, это приведет к исключению noUniqueBean, и приложение не запустится.