How do I map a REST web service using ServletContainerInitializer?
I want to map REST API using ServletContainerInitializer
and my code is
@Override
public void onStartup(Set<Class<?>> classes, ServletContext container)
throws ServletException {
// TODO Auto-generated method stub
Map<String, String> map=new HashMap<String, String>();
map.put("com.sun.jersey.config.property.packages", "org.pack");
ServletRegistration.Dynamic dispatcher = container.addServlet(
"restful", new ServletContainer());
dispatcher.setInitParameters(map);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/rest/*");
}
The application starts without any error, but no web service is created. Please suggest where am I going wrong and how to use ServletContainerInitializer
in any web application.
Thank you in advance
source to share
From what I understand about ServletContainerInitializer
is that it is based on the service provider template. I went through a tutorial about this a while ago and can't find it now. But you can see some of the requirements in the ServiceLoader
javadocs. It states:
A service provider is identified by placing a provider configuration file in the resource directory
META-INF/services
. The file name is the fully qualified binary name of the service type. The file contains a list of the fully qualified binary names of specific vendor classes, one per line.
The steps I took to get your example to work:
Create maven jar project with these dependencies
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
Create a directory META-INF/services
. You can put directly in src
or from Maven, I would like to put it src/main/resources
. They will both end up in the same place.
Create a file named javax.servlet.ServletContainerInitializer
and put the fully qualified name of your implementation in it ServletContainerInitializer
. Place the file in META-INF/services
. Here is my
META-INF/services/
javax.servlet.ServletContainerInitializer
// content
jersey.servlet.initializer.MyJerseyContainerInitializer
Here is the initializer class
package jersey.servlet.initializer;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class MyJerseyContainerInitializer implements ServletContainerInitializer{
@Override
public void onStartup(Set<Class<?>> set, ServletContext sc)
throws ServletException {
System.out.println("===============================================");
System.out.println(" onStartup() ");
System.out.println("===============================================");
Map<String, String> map = new HashMap<>();
map.put("com.sun.jersey.config.property.packages",
"jersey.servlet.initializer.rest");
ServletRegistration.Dynamic dispatcher = sc.addServlet(
"restful", new ServletContainer());
dispatcher.setInitParameters(map);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/rest/*");
}
}
And a simple recreation resource class
package jersey.servlet.initializer.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Path("/resource")
public class Resource {
@GET
public Response getResponse() {
return Response.ok("ServletContainerInitializer test OK!").build();
}
}
Then I built the jar and installed it in my local repo. Then another Maven web project was created adding the above jar to the project. It. Ran it on Tomcat 8, and also 7, and BAM
What's aside
jersey-serlvet.jar (which requires the class ServletContainer
you are using) already ships with com.sun.jersey.server.impl.container.servlet.JerseyServletContainerInitializer
. Why do we need to create our own?
EDIT
Its working on maven, but I want to do it without maven. Should I add the project jar to lib folder without maven.
Yes, you could build a fat jar for the .jar initializer (jersey jars included). Then you will need to host your web project WEB-INF/lib
. All Maven really helps with dependencies and creates a .war file. It will also put an initializer drum in the WEB-INF/lib
webapp. So just follow this example without using Maven. If you don't want to build a fat jar, make sure all dependencies are included in lib
source to share