Reputation: 3667
Using spring DefaultAnnotationHandlerMapping how can I lookup the Controller that would ultimately handle a given url.
I currently have this, but feels like there ought to be a cleaner way than iterating over 100s of request mappings:
public static Object getControllerForAction(String actionURL) {
ApplicationContext context = getApplicationContext();
AnnotationHandlerMapping mapping = (AnnotationHandlerMapping) context.getBean("annotationMapper");
PathMatcher pathMatcher = mapping.getPathMatcher();
for (Object key: mapping.getHandlerMap().keySet()) {
if (pathMatcher.match((String) key, actionURL)){
return mapping.getHandlerMap().get(key);
}
}
return null;
}
Upvotes: 4
Views: 3657
Reputation: 236
Above doesn't work in Spring 3.1. You can do the following instead.
Map<String, AbstractHandlerMethodMapping> map = WebApplicationContextUtils.getWebApplicationContext(servletContext).getBeansOfType(AbstractHandlerMethodMapping.class);
Iterator<AbstractHandlerMethodMapping> iter = map.values().iterator();
while (iter.hasNext()) {
AbstractHandlerMethodMapping ahmb = iter.next();
Iterator<Object> urls = ahmb.getHandlerMethods().keySet().iterator();
while (urls.hasNext()) {
Object url = urls.next();
logger.error("URL mapped: " + url);
}
}
Upvotes: 3
Reputation: 403551
For the purposes of this question, all of the interesting methods in DefaultAnnotationHandlerMapping
and its superclasses are protected, and so not visible to external code. However, it would be trivial to write a custom subclass of DefaultAnnotationHandlerMapping
which overrides these methods and makes them public
.
Since you need to be able to supply a path rather than a request object, I would suggest lookupHandler
of AbstractUrlHandlerMapping
would be a good candidate for this. It still needs you to supply it with a request object as well as the path, but that request object is only used to pass to the validateHandler() method, which does nothing, so you could probably supply a null there.
Upvotes: 3
Reputation: 100736
All mappers implement HandlerMapping
interface which has a getHandler()
method:
ApplicationContext context = getApplicationContext();
AnnotationHandlerMapping mapping = (AnnotationHandlerMapping) context.getBean("annotationMapper");
Object controller = mapping.getHandler().getHandler();
HandlerMapping.getHandler()
returns HandlerExecutionChain
, calling getHandler()
on that would return you the actual handler which - for controller mapper - would be the controller you're looking for.
Upvotes: 2