<?xml version="1.0"?>
<!--

    Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents; ]>
<chapter xmlns="http://docbook.org/ns/docbook"
         version="5.0"
         xml:lang="en"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
                             http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
         xml:id="jaxrs-resources">
    <title>JAX-RS Application, Resources and Sub-Resources</title>

    <para>This chapter presents an overview of the core JAX-RS concepts - resources and sub-resources.</para>

    <para>The JAX-RS &jax-rs.version; JavaDoc can be found online <link xlink:href="&jaxrs.release.uri;/apidocs/index.html">here</link>.
    </para>

    <para>The JAX-RS &jax-rs.version; specification draft can be found online <link
            xlink:href="http://jcp.org/en/jsr/summary?id=339">here</link>.
    </para>

    <section>
        <title>Root Resource Classes</title>

        <para>
            <emphasis>Root resource classes</emphasis>
            are POJOs (Plain Old Java Objects) that are annotated with &jaxrs.Path;
            have at least one method annotated with &jaxrs.Path; or a resource method designator annotation such as &jaxrs.GET;,
            &jaxrs.PUT;, &jaxrs.POST;, &jaxrs.DELETE;. Resource methods are methods of a resource class annotated with a resource
            method designator. This section shows how to use Jersey to annotate Java objects to create RESTful web services.
        </para>

        <para>The following code example is a very simple example of a root
            resource class using JAX-RS annotations. The example code shown here is
            from one of the samples that ships with Jersey, the zip file of which can
            be found in the maven repository
            <link xlink:href="http://central.maven.org/maven2/org/glassfish/jersey/examples/helloworld//&version;/">here</link>.
        </para>
        <para>
            <example>
                <title>Simple hello world root resource class</title>
                <programlisting language="java" linenumbering="numbered">package org.glassfish.jersey.examples.helloworld;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;

@Path("helloworld")
public class HelloWorldResource {
    public static final String CLICHED_MESSAGE = "Hello World!";

@GET
@Produces("text/plain")
    public String getHello() {
        return CLICHED_MESSAGE;
    }
}</programlisting>
            </example>
            Let's look at some of the JAX-RS annotations used in this example.
        </para>

        <section>
            <title>@Path</title>

            <para>The &jaxrs.Path; annotation's value is a relative URI path. In the example above, the Java class will be hosted at the URI path
                <literal>/helloworld</literal>. This is an extremely simple use of the &jaxrs.Path; annotation. What makes JAX-RS so useful is that you can embed variables in the URIs.
            </para>

            <para>
                <emphasis>URI path templates</emphasis>
                are URIs with variables embedded within the URI syntax. These variables are substituted at runtime in order for a resource to respond to a request based on the substituted URI. Variables are denoted by curly braces. For example, look at the following &jaxrs.Path; annotation:

                <programlisting language="java" linenumbering="unnumbered">@Path("/users/{username}")</programlisting>

                In this type of example, a user will be prompted to enter their name, and then a Jersey web service configured to respond to requests to this URI path template will respond. For example, if the user entered their username as "Galileo", the web service will respond to the following URL:
                <literal>http://example.com/users/Galileo</literal>
            </para>

            <para>To obtain the value of the username variable the &jaxrs.PathParam; may be used on method parameter of a request method, for example:
                <example>
                    <title>Specifying URI path parameter</title>
                    <programlisting language="java" linenumbering="numbered">@Path("/users/{username}")
public class UserResource {

    @GET
    @Produces("text/xml")
    public String getUser(@PathParam("username") String userName) {
        ...
    }
}</programlisting>
                </example>
                If it is required that a user name must only consist of
                lower and upper case numeric characters then it is possible to declare a
                particular regular expression, which overrides the default regular
                expression, "[^/]+", for example:
                <programlisting language="java">@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")</programlisting>
                In this type of example the username variable will only match user names that begin with one upper or lower case letter and zero or more alpha numeric characters and the underscore character. If a user name does not match that a 404 (Not Found) response will occur.
            </para>

            <para>A &jaxrs.Path; value may or may not begin with a '/', it makes no difference. Likewise, by default, a &jaxrs.Path; value may or may not end in a '/', it makes no difference, and thus request URLs that end or do not end in a '/' will both
                be matched.
            </para>
        </section>

        <section>
            <title>@GET, @PUT, @POST, @DELETE, ... (HTTP Methods)</title>

            <para>&jaxrs.GET;, &jaxrs.PUT;, &jaxrs.POST;, &jaxrs.DELETE; and &jaxrs.HEAD;
                are
                <emphasis>resource method designator</emphasis>
                annotations defined
                by JAX-RS and which correspond to the similarly named HTTP methods. In
                the example above, the annotated Java method will process HTTP GET
                requests. The behavior of a resource is determined by which of the HTTP
                methods the resource is responding to.
            </para>

            <para>The following example is an extract from the storage service
                sample that shows the use of the PUT method to create or update a
                storage container:
            </para>

            <para>
                <example>
                    <title>PUT method</title>
                    <programlisting language="java" linenumbering="numbered">@PUT
public Response putContainer() {
    System.out.println("PUT CONTAINER " + container);

    URI uri = uriInfo.getAbsolutePath();
    Container c = new Container(container, uri.toString());

    Response r;
    if (!MemoryStore.MS.hasContainer(c)) {
        r = Response.created(uri).build();
    } else {
        r = Response.noContent().build();
    }

    MemoryStore.MS.createContainer(c);
    return r;
}</programlisting>
                </example>
                By default the JAX-RS runtime will automatically support the methods HEAD and OPTIONS, if not explicitly
                implemented. For HEAD the runtime will invoke the implemented GET method (if present) and ignore the
                response entity (if set). A response returned for the OPTIONS method depends on the requested media type
                defined in the 'Accept' header. The OPTIONS method can return a response with a set of supported
                resource methods in the 'Allow' header or return
                a <link xlink:href="http://wadl.java.net/">WADL</link> document.
                See <link linkend="wadl">wadl section</link> for more information.
            </para>
        </section>

        <section>
            <title>@Produces</title>

            <para>
                The &jaxrs.Produces; annotation is used to specify the MIME media types of representations a resource can
                produce and send back to the client. In this example, the Java method will produce representations identified
                by the MIME media type "text/plain". &jaxrs.Produces; can be applied at both the class and method levels.
                Here's an example:
            </para>

            <para>
                <example>
                    <title>Specifying output MIME type</title>
                    <programlisting language="java" linenumbering="numbered">@Path("/myResource")
@Produces("text/plain")
public class SomeResource {
    @GET
    public String doGetAsPlainText() {
        ...
    }

    @GET
    @Produces("text/html")
    public String doGetAsHtml() {
        ...
    }
}</programlisting>
                </example>
                The
                <literal>doGetAsPlainText</literal>
                method defaults to the MIME type of the &jaxrs.Produces; annotation at the class level. The
                <literal>doGetAsHtml</literal>
                method's &jaxrs.Produces; annotation overrides the class-level &jaxrs.Produces; setting, and specifies that the
                method can produce HTML rather than plain text.
            </para>

            <para>If a resource class is capable of producing more that one MIME
                media type then the resource method chosen will correspond to the most
                acceptable media type as declared by the client. More specifically the
                Accept header of the HTTP request declares what is most acceptable. For
                example if the Accept header is "<literal>Accept: text/plain</literal>" then the
                <literal>doGetAsPlainText</literal>
                method will be invoked.
                Alternatively if the Accept header is "
                <literal>Accept: text/plain;q=0.9, text/html</literal>", which declares that the client can accept media types of
                "text/plain" and "text/html" but prefers the latter, then the
                <literal>doGetAsHtml</literal>
                method will be invoked.
            </para>

            <para>More than one media type may be declared in the same &jaxrs.Produces; declaration, for example:
            </para>

            <para>
                <example>
                    <title>Using multiple output MIME types</title>
                    <programlisting language="java" linenumbering="numbered">@GET
@Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson() {
    ...
}</programlisting>
                </example>
                The
                <literal>doGetAsXmlOrJson</literal>
                method will get
                invoked if either of the media types "application/xml" and
                "application/json" are acceptable. If both are equally acceptable then
                the former will be chosen because it occurs first.
            </para>

            <para>Optionally, server can also specify the quality factor for individual media types. These are
                considered if several are equally acceptable by the client. For example:</para>

            <para>
                <example>
                    <title>Server-side content negotiation</title>
                    <programlisting language="java" linenumbering="numbered">@GET
@Produces({"application/xml; qs=0.9", "application/json"})
public String doGetAsXmlOrJson() {
    ...
}</programlisting>
                </example>
                In the above sample, if client accepts both "application/xml" and "application/json" (equally),
                then a server always sends "application/json", since "application/xml" has a lower quality factor.
            </para>

            <para>The examples above refers explicitly to MIME media types for
                clarity. It is possible to refer to constant values, which may reduce
                typographical errors, see the constant field values of &jaxrs.core.MediaType;.
            </para>
        </section>

        <section>
            <title>@Consumes</title>
            <para>The &jaxrs.Consumes; annotation is used to specify the MIME media types of representations
                that can be consumed by a resource. The above example can be modified to set the cliched
                message as follows:
            </para>

            <para>
                <example>
                    <title>Specifying input MIME type</title>
                    <programlisting language="java" linenumbering="numbered">@POST
@Consumes("text/plain")
public void postClichedMessage(String message) {
    // Store the message
}</programlisting>
                </example>
            </para>

            <para>In this example, the Java method will consume representations
                identified by the MIME media type "text/plain". Notice that the resource
                method returns void. This means no representation is returned and
                response with a status code of 204 (No Content) will be returned to the client.
            </para>

            <para>&jaxrs.Consumes; can be applied at both the class and the method levels and more than one media type
                may be declared in the same &jaxrs.Consumes; declaration.
            </para>
        </section>
    </section>

    <section>
        <title>Parameter Annotations (@*Param)</title>

        <para>Parameters of a resource method may be annotated with parameter-based annotations to extract information
            from a request. One of the previous examples presented the use of &jaxrs.PathParam; to extract a path
            parameter from the path component of the request URL that matched the path declared in &jaxrs.Path;.
        </para>

        <para>&jaxrs.QueryParam; is used to extract query parameters from the Query component of the request URL.
            The following example is an extract from the sparklines sample:
        </para>

        <example>
            <title>Query parameters</title>
            <programlisting language="java" linenumbering="numbered">@Path("smooth")
@GET
public Response smooth(
    @DefaultValue("2") @QueryParam("step") int step,
    @DefaultValue("true") @QueryParam("min-m") boolean hasMin,
    @DefaultValue("true") @QueryParam("max-m") boolean hasMax,
    @DefaultValue("true") @QueryParam("last-m") boolean hasLast,
    @DefaultValue("blue") @QueryParam("min-color") ColorParam minColor,
    @DefaultValue("green") @QueryParam("max-color") ColorParam maxColor,
    @DefaultValue("red") @QueryParam("last-color") ColorParam lastColor) {
    ...
}</programlisting>
        </example>

        <para>If a query parameter "step" exists in the query component of the
            request URI then the "step" value will be extracted and parsed as a
            32 bit signed integer and assigned to the step method parameter. If "step"
            does not exist then a default value of 2, as declared in the &jaxrs.DefaultValue;
            annotation, will be assigned to the step method parameter. If the "step"
            value cannot be parsed as a 32 bit signed integer then a HTTP 404 (Not
            Found) response is returned. User defined Java types such as
            <literal>ColorParam</literal>
            may be used, which as implemented as
            follows:
        </para>

        <example>
            <title>Custom Java type for consuming request parameters</title>
            <programlisting language="java" linenumbering="numbered">public class ColorParam extends Color {

    public ColorParam(String s) {
        super(getRGB(s));
    }

    private static int getRGB(String s) {
        if (s.charAt(0) == '#') {
            try {
                Color c = Color.decode("0x" + s.substring(1));
                return c.getRGB();
            } catch (NumberFormatException e) {
                throw new WebApplicationException(400);
            }
        } else {
            try {
                Field f = Color.class.getField(s);
                return ((Color)f.get(null)).getRGB();
            } catch (Exception e) {
                throw new WebApplicationException(400);
            }
        }
    }
}</programlisting>
        </example>

        <para>In general the Java type of the method parameter may:</para>

        <orderedlist>
            <listitem>
                <para>Be a primitive type;</para>
            </listitem>

            <listitem>
                <para>Have a constructor that accepts a single
                    <literal>String</literal>
                    argument;
                </para>
            </listitem>

            <listitem>
                <para>Have a static method named
                    <literal>valueOf</literal>
                    or
                    <literal>fromString</literal>
                    that accepts a single
                    <literal>String</literal>
                    argument (see, for example,
                    <literal>Integer.valueOf(String)</literal>
                    and <literal>java.util.UUID.fromString(String)</literal>);
                </para>
            </listitem>
            <listitem>
                <para>Have a registered implementation of <literal>jakarta.ws.rs.ext.ParamConverterProvider</literal> JAX-RS
                    extension SPI that returns a <literal>jakarta.ws.rs.ext.ParamConverter</literal> instance capable of
                    a "from string" conversion for the type.
                     or
                </para>
            </listitem>

            <listitem>
                <para>Be <literal>List&lt;T&gt;</literal>,
                    <literal>Set&lt;T&gt;</literal>
                    or
                    <literal>SortedSet&lt;T&gt;</literal>, where
                    <literal>T</literal>
                    satisfies 2 or 3 above. The resulting collection is read-only.
                </para>
            </listitem>
        </orderedlist>

        <para>Sometimes parameters may contain more than one value for the same
            name. If this is the case then types in 5) may be used to obtain all
            values.
        </para>

        <para>If the &jaxrs.DefaultValue; is not used in conjunction with &jaxrs.QueryParam;
            and the query parameter is not present in the request then value will be
            an empty collection for<literal>List</literal>, <literal>Set</literal> or <literal>SortedSet</literal>,
            &lit.null; for other object types, and the Java-defined default for primitive types.
        </para>

        <para>The &jaxrs.PathParam; and the other parameter-based annotations, &jaxrs.MatrixParam;,
            &jaxrs.HeaderParam;, &jaxrs.CookieParam;, &jaxrs.FormParam; obey the same rules as &jaxrs.QueryParam;.
            &jaxrs.MatrixParam; extracts information from URL path segments. &jaxrs.HeaderParam; extracts information
            from the HTTP headers. &jaxrs.CookieParam; extracts information from the cookies declared in cookie related HTTP
            headers.
        </para>

        <para>&jaxrs.FormParam; is slightly special because it extracts information from a request representation that
            is of the MIME media type
            <literal>"application/x-www-form-urlencoded"</literal>
            and conforms to the encoding
            specified by HTML forms, as described here. This parameter is very useful for extracting information that is
            POSTed by HTML forms, for example the following extracts the form parameter named "name" from the POSTed form
            data:
        </para>

        <para>
            <example>
                <title>Processing POSTed HTML form</title>
                <programlisting language="java" linenumbering="numbered">@POST
@Consumes("application/x-www-form-urlencoded")
public void post(@FormParam("name") String name) {
    // Store the message
}</programlisting>
            </example>
        </para>

        <para>If it is necessary to obtain a general map of parameter name to
            values then, for query and path parameters it is possible to do the
            following:
        </para>

        <para>
            <example>
                <title>Obtaining general map of URI path and/or query parameters</title>
                <programlisting language="java" linenumbering="numbered">@GET
public String get(@Context UriInfo ui) {
    MultivaluedMap&lt;String, String&gt; queryParams = ui.getQueryParameters();
    MultivaluedMap&lt;String, String&gt; pathParams = ui.getPathParameters();
}</programlisting>
            </example>
        </para>

        <para>For header and cookie parameters the following:</para>

        <para>
            <example>
                <title>Obtaining general map of header parameters</title>
                <programlisting language="java" linenumbering="numbered">@GET
public String get(@Context HttpHeaders hh) {
    MultivaluedMap&lt;String, String&gt; headerParams = hh.getRequestHeaders();
    Map&lt;String, Cookie&gt; pathParams = hh.getCookies();
}</programlisting>
            </example>
        </para>

        <para>In general &jaxrs.core.Context; can be used to obtain contextual Java types related to the request or response.
        </para>

        <para>Because form parameters (unlike others) are part of the message entity, it is possible to do the following:</para>

        <para>
            <example>
                <title>Obtaining general map of form parameters</title>
                <programlisting language="java" linenumbering="numbered">@POST
@Consumes("application/x-www-form-urlencoded")
public void post(MultivaluedMap&lt;String, String&gt; formParams) {
    // Store the message
}</programlisting>
            </example>

            I.e. you don't need to use the &jaxrs.core.Context; annotation.
        </para>
        <para>Another kind of injection is the &jaxrs.BeanParam; which allows to inject the parameters described above into a
            single bean. A bean annotated with &jaxrs.BeanParam; containing any fields and appropriate
            <literal>*param</literal>
            annotation(like &jaxrs.PathParam;) will be initialized with corresponding request values in expected way as if these
            fields were in the resource class. Then instead of injecting request values like path param into a constructor parameters
            or class fields the &jaxrs.BeanParam; can be used to inject such a bean into a resource or resource method. The
            &jaxrs.BeanParam; is used this way to aggregate more request parameters into a single bean.
        </para>
        <example>
            <title>Example of the bean which will be used as &jaxrs.BeanParam;
            </title>
            <programlisting language="java" linenumbering="numbered">public class MyBeanParam {
    @PathParam("p")
    private String pathParam;

    @MatrixParam("m")
    @Encoded
    @DefaultValue("default")
    private String matrixParam;

    @HeaderParam("header")
    private String headerParam;

    private String queryParam;

    public MyBeanParam(@QueryParam("q") String queryParam) {
        this.queryParam = queryParam;
    }

    public String getPathParam() {
        return pathParam;
    }
    ...
}</programlisting>
        </example>
        <example>
            <title>Injection of MyBeanParam as a method parameter:</title>

            <programlisting language="java" linenumbering="numbered">@POST
public void post(@BeanParam MyBeanParam beanParam, String entity) {
    final String pathParam = beanParam.getPathParam(); // contains injected path parameter "p"
    ...
}</programlisting>
        </example>
        <para>The example shows aggregation of injections &jaxrs.PathParam;, &jaxrs.QueryParam; &jaxrs.MatrixParam;
            and &jaxrs.HeaderParam; into one single bean. The rules for injections inside the bean are the same as described above
            for these injections. The &jaxrs.DefaultValue; is used to define the default value for matrix parameter matrixParam.
            Also the &jaxrs.Encoded; annotation has the same behaviour as if it were used for injection in the resource method
            directly. Injecting the bean parameter into @Singleton resource class fields is not allowed (injections into method
            parameter must be used instead).
        </para>
        <para>&jaxrs.BeanParam; can contain all parameters injections
            (&jaxrs.PathParam;, &jaxrs.QueryParam;, &jaxrs.MatrixParam;, &jaxrs.HeaderParam;,
            &jaxrs.CookieParam;, &jaxrs.FormParam;). More
            beans can be injected into one resource or method parameters even if they inject the same request values. For example
            the following is possible:
        </para>
        <example>
            <title>Injection of more beans into one resource methods:</title>

            <programlisting language="java" linenumbering="numbered">@POST
public void post(@BeanParam MyBeanParam beanParam, @BeanParam AnotherBean anotherBean, @PathParam("p") pathParam,
String entity) {
    // beanParam.getPathParam() == pathParam
    ...
}</programlisting>
        </example>

    </section>

    <section>
        <title>Sub-resources</title>

        <para>&jaxrs.Path; may be used on classes and such classes are referred to as root resource classes. &jaxrs.Path;
            may also be used on methods of root resource classes. This enables common functionality for a number of resources
            to be grouped together and potentially reused.
        </para>

        <para>The first way &jaxrs.Path; may be used is on resource methods and such methods are referred to as
            <emphasis>sub-resource methods</emphasis>. The following example shows the method signatures for a root
            resource class from the jmaki-backend sample:
        </para>

        <para>
            <example>
                <title>Sub-resource methods</title>
                <programlisting language="java" linenumbering="numbered">@Singleton
@Path("/printers")
public class PrintersResource {

    @GET
    @Produces({"application/json", "application/xml"})
    public WebResourceList getMyResources() { ... }

    @GET @Path("/list")
    @Produces({"application/json", "application/xml"})
    public WebResourceList getListOfPrinters() { ... }

    @GET @Path("/jMakiTable")
    @Produces("application/json")
    public PrinterTableModel getTable() { ... }

    @GET @Path("/jMakiTree")
    @Produces("application/json")
    public TreeModel getTree() { ... }

    @GET @Path("/ids/{printerid}")
    @Produces({"application/json", "application/xml"})
    public Printer getPrinter(@PathParam("printerid") String printerId) { ... }

    @PUT @Path("/ids/{printerid}")
    @Consumes({"application/json", "application/xml"})
    public void putPrinter(@PathParam("printerid") String printerId, Printer printer) { ... }

    @DELETE @Path("/ids/{printerid}")
    public void deletePrinter(@PathParam("printerid") String printerId) { ... }
}</programlisting>
            </example>
        </para>

        <para>If the path of the request URL is "printers" then the resource methods not annotated with &jaxrs.Path;
            will be selected. If the request path of the request URL is "printers/list" then first the root resource class
            will be matched and then the sub-resource methods that match "list" will be selected, which in this case
            is the sub-resource method<literal>getListOfPrinters</literal>. So, in this example hierarchical matching
            on the path of the request URL is performed.
        </para>

        <para>The second way &jaxrs.Path; may be used is on methods
            <emphasis role="bold">not</emphasis>
            annotated
            with resource method designators such as &jaxrs.GET; or &jaxrs.POST;. Such methods are referred to as
            <emphasis>sub-resource locators</emphasis>. The following example shows the method signatures for
            a root resource class and a resource class from the optimistic-concurrency sample:
        </para>

        <para>
            <example>
                <title>Sub-resource locators</title>
                <programlisting language="java" linenumbering="numbered">@Path("/item")
public class ItemResource {
    @Context UriInfo uriInfo;

    @Path("content")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }

    @GET
    @Produces("application/xml")
        public Item get() { ... }
    }
}

public class ItemContentResource {

    @GET
    public Response get() { ... }

    @PUT
    @Path("{version}")
    public void put(@PathParam("version") int version,
                    @Context HttpHeaders headers,
                    byte[] in) {
        ...
    }
}</programlisting>
            </example>
        </para>

        <para>The root resource class
            <literal>ItemResource</literal>
            contains the
            sub-resource locator method
            <literal>getItemContentResource</literal>
            that
            returns a new resource class. If the path of the request URL is
            "item/content" then first of all the root resource will be matched, then
            the sub-resource locator will be matched and invoked, which returns an
            instance of the
            <literal>ItemContentResource</literal>
            resource class.
            Sub-resource locators enable reuse of resource classes. A method can be annotated with the
            &jaxrs.Path; annotation with empty path (<literal>@Path("/")</literal> or <literal>@Path("")</literal>) which
            means that the sub resource locator is matched for the path of the enclosing resource (without sub-resource path).
        </para>
        <para>
            <example>
                <title>Sub-resource locators with empty path</title>
                <programlisting language="java" linenumbering="numbered">@Path("/item")
public class ItemResource {

    @Path("/")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }
}</programlisting>
            </example>
        </para>

        <para>In the example above the sub-resource locator method <literal>getItemContentResource</literal>
            is matched for example for request path "/item/locator" or even for only "/item".
        </para>

        <para>In addition the processing of resource classes returned by
            sub-resource locators is performed at runtime thus it is possible to
            support polymorphism. A sub-resource locator may return different
            sub-types depending on the request (for example a sub-resource locator
            could return different sub-types dependent on the role of the principle
            that is authenticated). So for example the following sub resource locator is valid:
        </para>
        <para>
            <example>
                <title>Sub-resource locators returning sub-type</title>
                <programlisting language="java" linenumbering="numbered">@Path("/item")
public class ItemResource {

    @Path("/")
    public Object getItemContentResource() {
        return new AnyResource();
    }
}</programlisting>
            </example>
        </para>


        <para>Note that the runtime will not manage the life-cycle or perform any
            field injection onto instances returned from sub-resource locator methods.
            This is because the runtime does not know what the life-cycle of the
            instance is. If it is required that the runtime manages the sub-resources
            as standard resources the <literal>Class</literal> should be returned
            as shown in the following example:
        </para>
        <para>
            <example>
                <title>Sub-resource locators created from classes</title>
                <programlisting language="java" linenumbering="numbered">import javax.inject.Singleton;

@Path("/item")
public class ItemResource {
    @Path("content")
    public Class&lt;ItemContentSingletonResource&gt; getItemContentResource() {
        return ItemContentSingletonResource.class;
    }
}

@Singleton
public class ItemContentSingletonResource {
    // this class is managed in the singleton life cycle
}</programlisting>
            </example>
        </para>



        <para>JAX-RS resources are managed in per-request scope by default which means that
            new resource is created for each request.
            In this example the <literal>javax.inject.Singleton</literal> annotation says
            that the resource will be managed as singleton and not in request scope.
            The sub-resource locator method returns a class which means that the runtime
            will managed the resource instance and its life-cycle. If the method would return instance instead,
            the <literal>Singleton</literal> annotation would have no effect and the returned instance
            would be used.
        </para>

        <para>The sub resource locator can also return a <emphasis>programmatic resource model</emphasis>. See <link
                linkend="resource-builder">resource builder section</link> for information of how the programmatic resource
            model is constructed. The following example shows very simple resource returned from the sub-resource locator method.
        </para>


        <para>
            <example>
                <title>Sub-resource locators returning resource model</title>
                <programlisting language="java" linenumbering="numbered">import org.glassfish.jersey.server.model.Resource;

@Path("/item")
public class ItemResource {

    @Path("content")
    public Resource getItemContentResource() {
        return Resource.from(ItemContentSingletonResource.class);
    }
}</programlisting>
            </example>
        </para>
        <para>The code above has exactly the same effect as previous example. <literal>Resource</literal> is a resource
            simple resource constructed from <literal>ItemContentSingletonResource</literal>. More complex programmatic
            resource can be returned as long they are valid resources.
        </para>

    </section>


    <section>
        <title>Life-cycle of Root Resource Classes</title>

        <para>By default the life-cycle of root resource classes is per-request which,
            namely that a new instance of a root resource class is created every time
            the request URI path matches the root resource. This makes for a very
            natural programming model where constructors and fields can be utilized
            (as in the previous section showing the constructor of the
            <literal>SparklinesResource</literal>
            class) without concern for multiple
            concurrent requests to the same resource.
        </para>

        <para>In general this is unlikely to be a cause of performance issues.
            Class construction and garbage collection of JVMs has vastly improved over
            the years and many objects will be created and discarded to serve and
            process the HTTP request and return the HTTP response.
        </para>

        <para>Instances of singleton root resource classes can be declared by an instance of &jaxrs.core.Application;.
        </para>



        <para>Jersey supports two further life-cycles using Jersey specific annotations.</para>

        <table frame="all">
            <title>Resource scopes</title>
            <tgroup cols="4">
                <colspec colwidth="1*" />
                <colspec colwidth="1*" />
                <colspec colwidth="2*" />
                <colspec colwidth="5*" />
                <thead>
                    <row>
                        <entry>Scope</entry>
                        <entry>Annotation</entry>
                        <entry>Annotation full class name</entry>
                        <entry>Description</entry>
                    </row>
                </thead>
                <tbody>
                    <row><entry>Request scope</entry><entry>@RequestScoped (or none)</entry>
                        <entry>org.glassfish.jersey.process.internal.RequestScoped</entry>
                        <entry><emphasis>Default lifecycle </emphasis> (applied when no annotation is present). In this scope
                            the resource instance is created for each new request and used for processing of this request. If the
                            resource is used more than one time in the request processing, always the same instance will be used.
                            This can happen when a resource is a sub resource and is returned more times during the matching. In this
                            situation only one instance will serve the requests.</entry></row>
                    <row><entry>Per-lookup scope</entry><entry>@PerLookup</entry>
                        <entry>org.glassfish.hk2.api.PerLookup</entry>
                        <entry>In this scope
                            the resource instance is created every time it is needed for the processing even it handles
                            the same request.</entry></row>
                    <row><entry>Singleton</entry><entry>@Singleton</entry>
                        <entry>javax.inject.Singleton</entry>
                        <entry>In this scope there is only one instance per jax-rs application. Singleton resource can be either
                            annotated with @Singleton and its class can be registered using the instance of
                            &jaxrs.core.Application;. You can also create singletons by registering singleton instances
                            into &jaxrs.core.Application;.</entry></row>
                </tbody>
            </tgroup>
        </table>
    </section>

    <section>
        <title>Rules of Injection</title>

        <para>Previous sections have presented examples of annotated types, mostly
            annotated method parameters but also annotated fields of a class, for the
            injection of values onto those types.
        </para>

        <para>This section presents the rules of injection of values on annotated
            types. Injection can be performed on fields, constructor parameters,
            resource/sub-resource/sub-resource locator method parameters and bean
            setter methods. The following presents an example of all such injection
            cases:
        </para>

        <para>
            <example>
                <title>Injection</title>
                <programlisting language="java" linenumbering="numbered">@Path("{id:\\d+}")
public class InjectedResource {
    // Injection onto field
    @DefaultValue("q") @QueryParam("p")
    private String p;

    // Injection onto constructor parameter
    public InjectedResource(@PathParam("id") int id) { ... }

    // Injection onto resource method parameter
    @GET
    public String get(@Context UriInfo ui) { ... }

    // Injection onto sub-resource resource method parameter
    @Path("sub-id")
    @GET
    public String get(@PathParam("sub-id") String id) { ... }

    // Injection onto sub-resource locator method parameter
    @Path("sub-id")
    public SubResource getSubResource(@PathParam("sub-id") String id) { ... }

    // Injection using bean setter method
    @HeaderParam("X-header")
    public void setHeader(String header) { ... }
}</programlisting>
            </example>
        </para>

        <para>There are some restrictions when injecting on to resource classes
            with a life-cycle of singleton scope. In such cases the class fields or
            constructor parameters cannot be injected with request specific parameters. So, for example
            the following is not allowed.</para>

        <para>
            <example>
                <title>Wrong injection into a singleton scope</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
@Singleton
public static class MySingletonResource {

    @QueryParam("query")
    String param; // WRONG: initialization of application will fail as you cannot
                  // inject request specific parameters into a singleton resource.

    @GET
    public String get() {
        return "query param: " + param;
    }
}</programlisting>
            </example>
        </para>
        <para>
            The example above will cause validation failure during application initialization as singleton
            resources cannot inject request specific parameters. The same example would fail if the query
            parameter would be injected into constructor parameter of such a singleton. In other words, if you
            wish one resource instance to server more requests (in the same time) it cannot be bound
            to a specific request parameter.
        </para>
        <para>
            The exception exists for specific request objects which can injected even into
            constructor or class fields. For these objects the runtime will inject proxies
            which are able to simultaneously server more request. These request objects are
            <literal>HttpHeaders</literal>, <literal>Request</literal>, <literal>UriInfo</literal>,
            <literal>SecurityContext</literal>. These proxies can be injected using the &jaxrs.core.Context;
            annotation. The following example shows injection of proxies into the singleton resource class.
        </para>

        <para>
            <example>
                <title>Injection of proxies into singleton</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
@Singleton
public static class MySingletonResource {
    @Context
    Request request; // this is ok: the proxy of Request will be injected into this singleton

    public MySingletonResource(@Context SecurityContext securityContext) {
        // this is ok too: the proxy of SecurityContext will be injected
    }

    @GET
    public String get() {
        return "query param: " + param;
    }
}</programlisting>
            </example>
        </para>

        <para>
            To summarize the injection can be done into the following constructs:
        </para>
        <table frame="all">
            <title>Overview of injection types</title>
            <tgroup cols="2">
                <colspec colwidth="1*" />
                <colspec colwidth="5*" />
                <thead>
                    <row>
                        <entry>Java construct</entry>
                        <entry>Description</entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry>Class fields</entry>
                        <entry>
                            Inject value directly into the field of the class. The field can be private
                            and must not be final. Cannot be used in Singleton scope except proxiable types mentioned above.
                        </entry>
                    </row>
                    <row>
                        <entry>Constructor parameters</entry>
                        <entry>
                            The constructor will be invoked with injected values. If more
                            constructors exists the one with the most injectable parameters will be invoked.
                            Cannot be used in Singleton scope except proxiable types mentioned above.
                        </entry>
                    </row>
                    <row>
                        <entry>Resource methods</entry>
                        <entry>
                            The resource methods (these annotated with @GET, @POST, ...) can contain
                            parameters that can be injected when the resource method is executed.
                            Can be used in any scope.
                        </entry>
                    </row>
                    <row>
                        <entry>Sub resource locators</entry>
                        <entry>
                            The sub resource locators (methods annotated with @Path but not @GET, @POST, ...)
                            can contain parameters that can be injected when the resource method is executed.
                            Can be used in any scope.
                        </entry>
                    </row>
                    <row>
                        <entry>Setter methods</entry>
                        <entry>
                            Instead of injecting values directly into field the value can be injected into the
                            setter method which will initialize the field. This injection can be used only with &jaxrs.core.Context;
                            annotation. This means
                            it cannot be used for example for injecting of query params but it can be used for injections of
                            request. The setters will be called after the object creation and
                            only once. The name of the method does not necessary have a setter pattern. Cannot be used
                            in Singleton scope except proxiable types mentioned above.
                        </entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <para>
            The following example shows all possible java constructs into which the values can be injected.

            <example>
                <title>Example of possible injections</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
public static class SummaryOfInjectionsResource {
    @QueryParam("query")
    String param; // injection into a class field


    @GET
    public String get(@QueryParam("query") String methodQueryParam) {
        // injection into a resource method parameter
        return "query param: " + param;
    }

    @Path("sub-resource-locator")
    public Class&lt;SubResource&gt; subResourceLocator(@QueryParam("query") String subResourceQueryParam) {
        // injection into a sub resource locator parameter
        return SubResource.class;
    }

    public SummaryOfInjectionsResource(@QueryParam("query") String constructorQueryParam) {
        // injection into a constructor parameter
    }


    @Context
    public void setRequest(Request request) {
        // injection into a setter method
        System.out.println(request != null);
    }
}

public static class SubResource {
    @GET
    public String get() {
        return "sub resource";
    }
}</programlisting>
            </example>
        </para>


        <para>The &jaxrs.FormParam; annotation is special and may only be utilized on resource and sub-resource methods.
            This is because it extracts information from a request entity.
        </para>
    </section>

    <section>
        <title>Use of @Context</title>

        <para>Previous sections have introduced the use of &jaxrs.core.Context;. Chapter "Context" in the JAX-RS
            specification presents all the standard JAX-RS Java types that may be used with &jaxrs.core.Context;.
        </para>

        <para>When deploying a JAX-RS application using servlet then
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/ServletConfig.html">ServletConfig</link>,
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/ServletContext.html">ServletContext</link>,
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html">HttpServletRequest</link>
            and
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletResponse.html">HttpServletResponse</link>
            are available using &jaxrs.core.Context;.
        </para>
    </section>

    <section>
        <title>Programmatic resource model</title>

        <para>Resources can be constructed from classes or instances but also can be constructed from a programmatic resource
            model. Every resource created from resource classes can also
            be constructed using the programmatic resource builder api. See <link
                    linkend="resource-builder">resource builder section</link> for more information.
        </para>
    </section>

</chapter>
