views:

528

answers:

2

In Spring 2.0, is there a quick way to have a list of the current servlet context's mapped URLs from inside a Controller method?

I'm writing a method called getMappedUrls(), and the purpose of this method is to show what urls are mapped in the current servlet context.

This method is to be used to generate an small online doc of available services.

Thanks!

[Edit]

Kent Lai's answer works for me:

final Map<Object, AbstractUrlHandlerMapping> beans =
    getApplicationContext().getBeansOfType(AbstractUrlHandlerMapping.class);
for (final AbstractUrlHandlerMapping bean : beans.values())
{
    final Map<String, Object> mapping = bean.getHandlerMap();
    for(final String url : mapping.keySet())
        urls.add(url);
}
+1  A: 

The servlet spec hides this information from the servlet code. You can only get the context path used for the current request. If you can get to the web.xml, you would be able to infer the mappings from there, but that's a bit of a hack. You could also have each servlet register itself upon startup.

sblundy
+3  A: 

This sounds like an interesting idea, and so I went to dig inside the Spring Web MVC source code to find out if there is a way.

First I turned on debug for my spring framework logging (log4j), and I noticed mappings are done in my org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping class (since I am using that).

Digging furthur, I noticed that all handler mappings are added to a handler map, which you can obtain from org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#getHandlerMap

Assuming you are using a handler that derives from it.

Next, I find out that DispatcherServlet is using the HandlerMapping, which AbstractUrlHandlerMapping (and AbstractHandlerMapping) implements, to resolve the url (well obviously they have to use it). And it turns out that DispatcherServlet holds another list of handlerMappings

org.springframework.web.servlet.DispatcherServlet#handlerMappings

The bad news here is, well it is a protected class instance variable.

So my best recommendation (if this can be considered best) that you can do to find out all the mapped url is

  1. Get hold of an instance of ApplicationContext.
  2. Find out all beans of at least type AbstractUrlHandlerMapping (since anything furthur up does not tell you any mapped url).
  3. Iterate the list and call getHandlerMap and get all the keySet, which is the mapped url.

Note that this is what I dig out from my usage of @RequestMapping annotations. I am unsure how different it is if you are mapping urls in your spring configuration files.

Kent Lai
Thanks, it works great!
Sébastien RoccaSerra