Add prefix to URLs of all the controller classes in the package

10,064

You might want to look at the convention over configuration support of Spring 3, specifically ControllerClassNameHandlerMapping. Effectively you don't define the location of the URL in a @RequestMapping but it's defined by the package location of the handler.

If you want to have the mapped URLs reflect the package name of controller then you should set the basePackage property of the ControllerClassNameHandlerMapping. The documentation says

Set the base package to be used for generating path mappings, including all subpackages underneath this packages as path elements. Default is null, using the short class name for the generated path, with the controller's package not represented in the path. Specify a base package like "com.mycompany.myapp" to include subpackages within that base package as path elements, e.g. generating the path "/mymodule/buyform" for the class name "com.mycompany.myapp.mymodule.BuyForm". Subpackage hierarchies are represented as individual path elements, e.g. "/mymodule/mysubmodule/buyform" for the class name "com.mycompany.myapp.mymodule.mysubmodule.BuyForm".

So, an example beans definition might be

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
    <property name="basePackage" value="com.company.project"/>
</bean>
<context:component-scan base-package="com.company.project.ws"/>

And your controllers might look like

package com.company.project.ws;
@Controller
public class Service1 {
    // your controller methods
}
Share:
10,064
Shreerang
Author by

Shreerang

Updated on July 21, 2022

Comments

  • Shreerang
    Shreerang almost 2 years

    I am developing a RESTful service using Spring 3.0 running on Tomcat Apache 6.0 environment. The Spring DispatcherServlet is configured at "/spring/*". The Spring servlet handles multiple clients and has many Controllers in the application. I am adding a new Controller for the REST service. I want all of my controller classes to have a identification prefix like "ws" (web-service) so that the complete URL to a resource looks like this:
    http://<server>:<port>/<context>/spring/ws/service1

    The only way I found with Spring annotation is to use @RequestMapping like this:

    @Controller
    @RequestMapping("/ws/service1")
    public class Service1 {
    
    @RequestMapping(method=RequestMethod.GET)
    @ResponseBody
    public String getHtml() { ... }  
    
    ....
    }
    

    But since I have dozens of classes, I don't want to put "/ws" prefix in each class. So that if another developer adds a new service, he does not have to remember to put this prefix and also if we decide to change the prefix name from "/ws" to something else, I don't have to change all the files. I found that @RequestMapping annotation is only applicable to Methods or Classes and not at the package level.

    Is there any way I can configure that all my REST Controllers are accessed with the prefix?

    Please note that I can not change the web.xml URL mapping of Spring servlet since, there are other Controllers which are running with that URL.

  • Shreerang
    Shreerang almost 13 years
    Yes, I have in fact looked into that. Can you please tell me if it is possible to have URL mapping which takes into consideration the package names? For example if fully qualified class name is "com.ws.Service1" then would it map to URL "/ws/service1" and so on?
  • ptomli
    ptomli almost 13 years
    Yes, that's possible. It's not explained in the reference but the JavaDoc has the necessary pointers. I've updated the answer to reflect how you would achieve this. You might also want to look at the pathPrefix property for the ControllerClassNameHandlerMapping, if you want to prefix your path.
  • Shreerang
    Shreerang almost 13 years
    This looks great, I tried that but I am getting below error: javax.servlet.ServletException: No adapter for handler [com.coresecurity.wsapi.ws.Service@407d11]: Does your handler implement a supported interface like Controller? Even though I have defined bean <bean class= "org.springframework.web.servlet.mvc.SimpleControllerHandler‌​Adapter"/> Any suggestions?
  • ptomli
    ptomli almost 13 years
    You might want to take a look at AnnotationMethodHandlerAdapter, and the reference for annotation based controllers. static.springsource.org/spring/docs/3.0.x/reference/….
  • Shreerang
    Shreerang almost 13 years
    Yes, I tried AnnotationMethodHandlerAdapter and it worked. I am accepting this as answer because it sure solves the problem I asked. However, I took a different approach to implement solution in my project. I will put it as a different answer for other's benefit.