Blog post by Anadi Misra on Spring Framework with image banner of pottery carving.

Auto URL mapping in Spring

A brief introduction on how to enable a convention over configuration approach of URL mapping for controllers.

Posted by Anadi Misra on November 10, 2011 · 4 mins read

A brief introduction on how to enable a convention over configuration approach of URL mapping for controllers.

ControllerClassnameHandlerMapping is a very good way when it comes to cleaning up spring xml configurations and as I see it enforcing a sort of convention within your application of building URLs. Detailed documentation can be found here so i’ll skip that part and summarize it before I go to other things. Provided you stick to a naming convention with your Controllers, Views it enables creating clean URLs with a sort of uniform access for your application, reduces the amount of code you write. Which is to say that a URL /project will be mapped to ProjectController, and not just that if you’ve added a POJO bean called project in the Model you return, you don’t need to name to view or the attribute you are adding before you forward or redirect to it.

But there are some lesser know things about using which got me stuck before I could fully utilize this feature and hence this blog post aims at elaborating those parts (not to mention it based on all I learned trying to solve issues in my application and doing those long searches in Spring Forums.); it can be my bad Google skills though but I have always been a refer documentation and forums person than search (yes, some people just can’t get a thing done smart :-P). I start listing it out now:

You will have to set the property default handler when configuring it as a bean in your spring XML. This is if you are using SimpleControllerHandlerAdapter, not specifying a default handler in such a case gives the following exception:

javax.servlet.ServletException: No adapter for handler [your.controller.ProjectController@6d78ddf4]: 
Does your handler implement a supported interface like Controller?
org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:967)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:760)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)

So, you should provide a handler to this mapping definition in your spring xml then

<!-- Bind to a naming convention for controllers and views -->
 <beans:bean id="classnameControllerMappings"
  class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"
  <beans:property name="defaultHandler">
   <beans:bean
    class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
  </beans:property>
 </beans:bean>

There is another approach; which lets you through without having to tweak too much in the configuration: useAnnotationMethodHandlerAdapterand annotate the methods to be invoked for a URI through the @RequestMappingannotations, your bean definitions then look like as follows

<!-- Bind to a naming convention for controllers and views -->
 <beans:bean id="classnameControllerMappings" 
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
 </beans:bean>
<!-- Enables annotated POJO @Controllers -->
 <beans:bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

Paths mapped by this approach

ProjectController --> /project /project/*

which means a URL like

/project/create

will be mapped, but a

/project/details/show

won’t. So you have to ensure your URLs do not have a third path element. That won’t work with this approach and is not a part the class specification.

Hope this helps in easier url path mappings!