<?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 jakarta.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>jakarta.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>jakarta.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>
