Is it possible to have multiple jersey servlets in one single web.xml? I am trying to do the RESTfull versioning in this way:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>myapi</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context-v1.xml /WEB-INF/context-v2.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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.myapi.rest.v1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST-V1</servlet-name>
<url-pattern>/v1/*</url-pattern>
</servlet-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.myapi.rest.v2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST-V2</servlet-name>
<url-pattern>/v2/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
But the spring context-v1 and context-v2 should be loaded separately? Because they have beans, which have the same name etc.
EDIT:
If you look in my console output it's loading the resources (admin/info) two times for each servlet:
15.07.2012 14:47:08 com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.myapi.rest.v1
15.07.2012 14:47:08 com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.myapi.rest.v1.LOAdminResource
class com.myapi.rest.v1.LOInfoResource
15.07.2012 14:47:08 com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.servlet.SpringServlet getContext
INFO: Using default applicationContext
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, adminResource_v2, of type com.myapi.rest.v2.LOAdminResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, infoResource_v2, of type com.myapi.rest.v2.LOInfoResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, adminResource_v1, of type com.myapi.rest.v1.LOAdminResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, infoResource_v1, of type com.myapi.rest.v1.LOInfoResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.8 06/24/2011 12:17 PM'
15.07.2012 14:47:09 com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.myapi.rest.v2
15.07.2012 14:47:09 com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.myapi.rest.v2.LOAdminResource
class com.myapi.rest.v2.LOInfoResource
15.07.2012 14:47:09 com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.servlet.SpringServlet getContext
INFO: Using default applicationContext
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, adminResource_v2, of type com.myapi.rest.v2.LOAdminResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, infoResource_v2, of type com.myapi.rest.v2.LOInfoResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, adminResource_v1, of type com.myapi.rest.v1.LOAdminResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.spi.spring.container.SpringComponentProviderFactory registerSpringBeans
INFO: Registering Spring bean, infoResource_v1, of type com.myapi.rest.v1.LOInfoResource as a root resource class
15.07.2012 14:47:09 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.8 06/24/2011 12:17 PM'
The thing is that when you use Jersey and Spring together, the Jersey/Spring servlet goes through all available Spring beans and registers every resource and provider classes it will find among them.
If you have multiple Jersey/Spring servlets using the same (root) context and thus sharing bean definitions, then the procedure is performed for each such servlet and resource and provider class are registered several times.
In order to avoid multiple registration of the same bean, define such beans in a child context of a respective Jesrey/Spring servlet.
It is even not necessary to provide initialization parameters for declaring classes in the web.xml unless a mixture of Spring-managed and Jersey-managed classes is required.
Yes you can specify two or more servlets into a web.xml . Remember to specify a different servlet-mapping for each one.
the initParameter loadOnStartup defines the order in which the servlet are loaded (in this case first servletOne and then servletTwo).
One more possibility is to override one method in
com.sun.jersey.spi.spring.container.servlet.SpringServlet
. The initiate method looks like this (version 1.19.1):If you change the code in a subclass like this, then you can filter out the unwanted spring beans based on your criteria (for example package name):
A bit hacky solution, but works for us perfectly.
I know this topic is old to answer. But my answer can help others.
We can configure multiple resource packages in web.xml with these delimiters :
Example :