Reputation: 587
I have a Jersey / Spring REST servlet. I am trying to use URL versioning mechanism to have 2 versions of the same resource. What is the best way to solve this ?
This is my web.xml I am trying to load up 2 jersey servlets
<servlet>
<servlet-name>REST_V1</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.comp.resource.v1</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>REST_V1</servlet-name>
<url-pattern>/v1/*</url-pattern>
</servlet-mapping>
This is the V2 mapping
<servlet>
<servlet-name>REST_V2</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.comp.resource.v2</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>REST_V2</servlet-name>
<url-pattern>/v2/*</url-pattern>
</servlet-mapping>
I have defined 2 spring components, with the same resource path in their respective packages
package com.comp.resource.v1;
@Controller
@Path("/user")
public class User_V1 {
}
For V2
package com.comp.resource.v2;
@Controller
@Path("/user")
public class User_V2 {
}
I am seeing a conflicting URI Template error for the resource /user Is there a better way to solve this ? Any help wold be appreciated
Upvotes: 1
Views: 800
Reputation: 587
Seems like the issue is with how spring beans are loaded. In the web.xml if you have contextConfigLocation outside of the Jersey to load up all the beans, then both REST_V1 and REST_V2 servlet conflicts with the same resource name.
Here is what I changed in the application context. Removed scanning of resource package from global applicationContext.xml
<context:annotation-config />
<context:component-scan base-package="com.comp.*">
<context:exclude-filter type="regex" expression="com.comp.resource.*"/>
</context:component-scan>
Added 2 more applicationContext, for each servlet
applicationContext_V1.xml
<context:annotation-config />
<context:component-scan base-package="com.comp.resource.v1"/>
applicationContext_V2.xml
<context:annotation-config />
<context:component-scan base-package="com.comp.resource.v2"/>
Added reference to these applicationContext file in jersey configuration in web.xml
<servlet>
<servlet-name>REST_V1</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.comp.resource.v1</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext_V1.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>REST_V1</servlet-name>
<url-pattern>/v1/*</url-pattern>
</servlet-mapping>
and for REST_V2
<servlet>
<servlet-name>REST_V2</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.comp.resource.v2</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext_V2.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>REST_V2</servlet-name>
<url-pattern>/v2/*</url-pattern>
</servlet-mapping>
Upvotes: 1