Chapter 4. Deploying a RESTful Web Service
Prev |  | Next

Links: Table of Contents | Single HTML

## Chapter 4. Deploying a RESTful Web Service

JAX-RS provides a deployment agnostic abstract class Application for declaring root resource and provider classes, and root resource and provider singleton instances. A Web service may extend this class to declare root resource and provider classes. For example,

Example 4.1. Deployment agnostic application model

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

Alternatively it is possible to reuse one of Jersey's implementations that scans for root resource and provider classes given a classpath or a set of package names. Such classes are automatically added to the set of classes that are returned by`getClasses`. For example, the following scans for root resource and provider classes in packages "org.foo.rest", "org.bar.rest" and in any sub-packages of those two:

Example 4.2. Reusing Jersey implementation in your custom application model

    public class MyApplication extends ResourceConfig {
        public MyApplication() {
            packages("org.foo.rest;org.bar.rest");
        }
    }

There are multiple deployment options for the class that implements Application interface in the Servlet 3.0 container. For simple deployments, no `web.xml` is needed at all. Instead, an @ApplicationPath annotation can be used to annotate the user defined application class and specify the base resource URI of all application resources:

Example 4.3. Deployment of a JAX-RS application using `@ApplicationPath` with Servlet 3.0

    @ApplicationPath("resources")
    public class MyApplication extends ResourceConfig {
        public MyApplication() {
            packages("org.foo.rest;org.bar.rest");
        }
        ...
    }

Please note that there is more which can be set or called during execution of ResourceConfig descendants constructor, see ResourceConfig javadoc for more details.

You also need to set maven-war-plugin attribute failOnMissingWebXml to false in pom.xml when building .war without web.xml file using maven:

Example 4.4. Configuration of maven-war-plugin in `pom.xml` with Servlet 3.0

    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
        ...
    </plugins>

Another deployment option is to declare JAX-RS application details in the `web.xml`. This is usually suitable in case of more complex deployments, e.g. when security model needs to be properly defined or when additional initialization parameters have to be passed to Jersey runtime. JAX-RS 1.1 specifies that a fully qualified name of the class that implements Application may be declared in the `<servlet-name>` element of the JAX-RS application's `web.xml`. This is supported in a Web container implementing Servlet 3.0 as follows:

Example 4.5. Deployment of a JAX-RS application using `web.xml` with Servlet 3.0

    <web-app>
        <servlet>
            <servlet-name>org.foo.rest.MyApplication</servlet-name>
        </servlet>
        ...
        <servlet-mapping>
            <servlet-name>org.foo.rest.MyApplication</servlet-name>
            <url-pattern>/resources</url-pattern>
        </servlet-mapping>
        ...
    </web-app>

Note that the `<servlet-class>` element is omitted from the servlet declaration. This is a correct declaration utilizing the Servlet 3.0 extension mechanism. Also note that `<servlet-mapping>` is used to define the base resource URI.

When running in a Servlet 2.x then instead it is necessary to declare the Jersey specific servlet and pass the Application implementation class name as one of the servlet's `init-param` entries:

Example 4.6. Deployment of your application using Jersey specific servlet

    <web-app>
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>javax.ws.rs.Application</param-name>
                <param-value>org.foo.rest.MyApplication</param-value>
            </init-param>
            ...
        </servlet>
        ...
    </web-app>

If there is no configuration to be set and deployed application consists only from resources and providers stored in particular packages, Jersey can scan them and register automatically:

Example 4.7. Using Jersey specific servlet without an application model instance

    <web-app>
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>org.foo.rest;org.bar.rest</param-value>
            </init-param>
            ...
        </servlet>
        ...
    </web-app>

JAX-RS also provides the ability to obtain a container specific artifact from an Application instance. For example, Jersey supports using Grizzly as follows:

    HttpHandler endpoint = RuntimeDelegate.getInstance().createEndpoint(new MyApplication(), HttpHandler.class);

Jersey also provides Grizzly helper classes to deploy the HttpHandler instance at a base URL for in-process deployment.

The Jersey samples provide many examples of Servlet-based and Grizzly-in-process-based deployments.

## 4.1. Auto-Discoverable Features

For a few modules provided by Jersey there is no need to explicitly register their Features as these `Feature`s are discovered and registered in the Configuration (on client/server) automatically by Jersey when the modules implementing these features are present on the classpath during the an application deployment. The modules that are automatically discovered include:

- `jersey-media-moxy` (JSON part)

- `jersey-media-json-processing`

- `jersey-bean-validation`

Besides these modules there are also few features/providers present in `jersey-server` module that are discovered by this mechanism and their availability is affected by Jersey auto-discovery support configuration (see Section 4.1.1, “Configuring the Feature Auto-discovery mechanism”):

- WadlFeature - enables WADL processing.

- UriConnegFilter - a URI-based content negotiation filter.

### Note

Auto discovery functionality is in Jersey supported by implementing an internal SPI `AutoDiscoverable` interface. This interface is not public at the moment, so be careful when using it.

### 4.1.1. Configuring the Feature Auto-discovery mechanism

The auto-discovery of features in Jersey that is enabled by default can be disabled by using special (common/server/client) properties:

Common auto discovery properties

- CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE

  Disables auto discovery globally on client/server.

- CommonProperties.JSON_PROCESSING_FEATURE_DISABLE

  Disables configuration of Json Processing (JSR-353) feature.

- CommonProperties.MOXY_JSON_FEATURE_DISABLE

  Disables configuration of MOXy Json feature.

For each of these properties there is a client/server counter-part that only disables the feature on the client or server respectively (see ClientProperties/ServerProperties). Each of these client/server specific auto-discovery related properties overrides the value of the related common property (if set).

### Note

In case an auto-discoverable feature is disabled then all the featured, components and/or properties, registered with the feature by default using the auto-discovery mechanism have to be registered manually.

## 4.2. Turn off classpath scanning

Jersey uses common Service Loader or Lookup design pattern to obtain all service implementations. It means it lookups whole class path to find appropriate files in `META-INF/services/`. The class path lookup may be time consuming. The more jar or war files on class path the lookup is longer. If you count any ms of application bootstrap you can generally disable services lookup.

Jersey is looking for implementation of following SPIs

- `AutoDiscoverable` (server, client) - it means if you disable service loading the AutoDiscoverable feature is automatically disabled too

- `MessageBodyReader` (server, client)

- `MessageBodyWriter` (server, client)

- `HeaderDelegateProvider` (server, client)

- `ComponentProvider` (server)

- `ContainerProvider` (server)

- `AsyncContextDelegateProvider` (server/servlet)

In all cases it is possible to register an SPI implementation class or instance programmatically. Therefore you can disable services lookup in Jersey and save dozens of ms during application initialization. The services lookup in Jersey that is enabled by default can be disabled by using special property CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE. There is a client/server counter-part that only disables the feature on the client or server respectively: ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE/ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE. The client/server specific property overrides the value of the related common property (if set).

For example, following code snippet registers different types of implementations: `ContainerRequestFilter`, `Feature`, `ComponentProvider` and `ContainerProvider`:

Example 4.8. Registering SPI implementations using ResourceConfig

    final ResourceConfig resourceConfig = new ResourceConfig(MyResource.class);
    resourceConfig.register(org.glassfish.jersey.server.filter.UriConnegFilter.class);
    resourceConfig.register(org.glassfish.jersey.server.validation.ValidationFeature.class);
    resourceConfig.register(org.glassfish.jersey.server.spring.SpringComponentProvider.class);
    resourceConfig.register(org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainerProvider.class);
    resourceConfig.property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);

Prev |  | Next
Chapter 3. JAX-RS Application, Resources and Sub-Resources | Home | Chapter 5. Client API