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