Deployment

Deployment фото
Author: Tatyana Milkina

This article describes how to build RESTful Web Services using Jersey.

1. Server Configuration

We are using on Jboss 7 AS server for deployment. By default JBoss AS 7 is working with RESTEasy and incompatible with Jersey. To fix this issue change Jboss configuration file JBOSS_HOME/standalone /configuration/standalone.xml or JBOSS_HOME/domain /configuration/domain.xml. Find and delete such two lines in them:

                      
...<extension module="org.jboss.as.jaxrs"/> ...
...<subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/> ...

If not to switch off RESTEasy, the application won't be deployed with the exception: "Only one JAX-RS Application Class allowed." 

2. Servlet-based Deployment

Jersey integrates with any Servlet containers supporting at least Servlet 2.5 specification. 

Deployed web service can be accessed by http://<HOST>/<PROJECT>/exams/1 address.

Example 2.1. Resource

Let's start with our resource web service, which will be the same for each type of deployment:

                              
package com.examclouds;
...
@Path("exams")
public class ExamService {
    Map<Integer, String> exams;

    public ExamService() {
        exams = new HashMap<Integer, String>();
        exams.put(1, "OCJP 6");
        exams.put(2, "OCEJPAD 6");
        exams.put(3, "OCEJWSD 6");
    }

    @GET
    @Path("/{id}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getExam(@PathParam("id") int id) {
        return exams.get(id);
    }
}

Example 2.2. Maven Dependency

Add dependency to pom.xml:

   <dependency>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-servlet</artifactId>
       <version>1.17</version>
   </dependency>

2.1. Deployment with agnostic abstract class Application

JAX-RS has a deployment agnostic abstract class Application that helps to declare root resource, provider classes, and provider singleton instances. The Application class has getClasses() and getSingletons() methods. The getClasses() method returns the list of classes to deploy in the JAX-RS environment and getSingletons() - actual instances that were created within the implementation of the Application class.

Example 2.3. Extension of the Application class

Web service should extend Application class to declare root resource and provider classes:

package com.examclouds;
...
public class ExamApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(ExamService.class);
        return s;
    }
}

Example 2.4. The web.xml for RESTful Web Services

Declare the Jersey specific servlet and pass the ExamApplication class name as the servlet’s init-param in web.xml:

<servlet>
    <servlet-name>ExamApplication</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.examclouds.ExamApplication</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ExamApplication</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

2.2. Deployment with Jersey ResourceConfig

Jersey has its own implementation of Application class - ResourceConfig. It can be directly instantiated or extended. In the case of extension, the configuration is done in the constructor of the extended class.

The advantages of the ResourceConfig over the Application class - more simple registration of JAX-RS components, such as scanning for root resource and provider classes in a provided classpath or in a set of package names.

Example 2.5. Extension of ResourceConfig class

The ExamApplication class from the example that extends from the PackagesResourceConfig searches for JAX-RS components in the “com.examclouds” package:

public class ExamApplication extends PackagesResourceConfig {
    public ExamApplication() {
        super("com.examclouds");
    }
}

Example 2.6. Declare Jersey Specific Servlet in web.xml

<servlet>
    <servlet-name>ExamApplication</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.api.core.PackagesResourceConfig</param-name>
        <param-value>com.examclouds.ExamApplication</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ExamApplication</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

2.3. Deployment with @ApplicationPath annotation

This type of deployment doesn't need web.xml and applicable for Servlet 3.0 applications. Instead, an @ApplicationPath is used to annotate defined by user application class and specify the base URI for all resources of the application.

Example 2.7. Using of @ApplicationPath

@ApplicationPath("")
public class ExamApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(ExamService.class);
        return s;
    }
}

Example 2.8. The setting of failOnMissingWebXml in web.xml

The maven-war-plugin attribute failOnMissingWebXml should be set to false:

 
<plugins>
    ...
    <plugin>
        <groupId>org.jboss.as.plugins</groupId>
        <artifactId>jboss-as-maven-plugin</artifactId>
        <version>7.1.1.Final</version>
        <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
    </plugin>
</plugins>

2.4. Deployment with Jersey specific servlet without an application model instance

This deployment method is used if resources and providers of deployed application are stored in the particular packages. In this case, Jersey will find and register them automatically. Define package with root resources in web.xml:

Example 2.8. Declare Jersey Specific Servlet in web.xml

 
<servlet>
    <servlet-name>ExamApplication</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
         <param-name>jersey.config.server.provider.packages</param-name>
         <param-value>com.examclouds;</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ExamApplication</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

3. Enterprise Java Beans

Stateless and Singleton Session beans can be implemented as JAX-RS resources, providers, or Application classes. EJBs are discovered by JAX-RS implementors by inspecting annotations on classes (or local interfaces), but not in the deployment descriptors (ejb-jar.xml).

Example 3.1. EJB implemented as JAX-RS resource

The example demonstrates how to implement stateless EJB as a JAX-RS resource.

@Stateless
@Path("exams")
public class ExamService {
    Map<Integer, String> exams;

    public ExamService() {
        exams = new HashMap<Integer, String>();
        exams.put(1, "OCJP 6");
        exams.put(2, "OCEJPAD 6");
        exams.put(3, "OCEJWSD 6");
    }

    @GET
    @Path("/{id}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getExam(@PathParam("id") int id) {
        return exams.get(id);
    }
}
Читайте также:
Комментарии