Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine Controller for given url (spring)

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;
}
like image 974
case nelson Avatar asked Oct 18 '25 18:10

case nelson


2 Answers

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.

like image 161
skaffman Avatar answered Oct 20 '25 07:10

skaffman


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);
    }           
}
like image 32
alvins Avatar answered Oct 20 '25 08:10

alvins