views:

607

answers:

4

I think what I need is called reverse url resolution in Django. Lets say I have an AddUserController that goes something like this:

@Controller
@RequestMapping("/create-user")
public class AddUserController{ ... }

What I want is some way to dynamically find the url to this controller or form a url with parameters to it from the view (JSP), so I don't have to hardcode urls to controllers all over the place. Is this possible in Spring MVC?

+2  A: 

Have you considered having a bean that aggregates all of the controller URLs you need into a HashMap and then adding this controller/URL Map to any model that requires it? Each Spring controller has the ability to call an init() method, you could have each controller add it's name and URL to the controller/URL map in the init() methods so it would be ready to use when the controllers go live.

jottos
I'll try making my own HandlerInterceptor that aggregates the controller->url mappings and ads them to every ModelAndView for every request. But still, this doesn't get even close to what is possible with django's url resolution and reverse resolution.
Vasil
I see your point. Django nicely centralizes the url patterns even allowing names for them. I've jumped into the Spring source in the past to figure out how things get done, but its not a lot of fun
jottos
+1  A: 

You can get access to the request object in any JSP file without having to manually wire in or manage the object into the JSP. so that means you can get the url path off the request object, have a google into JSP implicit objects.

Here is a page to get you started http://www.exforsys.com/tutorials/jsp/jsp-implicit-and-session-objects.html

Chiwai Chan
hmmm... I'm not really interested in getting the url from an incomming request. What I want to do is give a controller Class or reference and get back a url that will be served by that conroller. Which as it turns out is impossible "out of the box".
Vasil
+1  A: 

I would probably try to build a taglib which inspects the annotations you're using in order to find a suitable match:

<x:url controller="myController">
    <x:param name="action" value="myAction"/>
</x:url>

Taglib code might be something roughly like

  1. Ask Spring for configured beans with the @Controller annotation
  2. Iterate in some suitable order looking for some suitable match on the controller class or bean name
  3. If the @RequestMapping includes params, then substitute them
  4. Return the string

That might work for your specific case (@RequestMapping style) but it'll likely get a bit hairy when you have multiple mappings. Perhaps a custom annotation would make it easier.

Edit:

AbstractUrlHandlerMapping::getHandlerMap, which is inherited by the DefaultAnnotationHandlerMapping you're most likely using, returns a Map of URL to Handler

Return the registered handlers as an unmodifiable Map, with the registered path as key and the handler object (or handler bean name in case of a lazy-init handler) as value.

So you could iterate over that looking for a suitable match, where "suitable match" is whatever you want.

ptomli
+1  A: 

I submitted an enhancement request for this back in May. You can follow/vote/comment here: http://jira.springsource.org/browse/SPR-5779

cherro
I am actually surprised there is no built-in way of doing this already. This is one of the features I love in Django/Python.
Andrei Taranchenko