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

    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

    Copyright (c) 2012-2016 Oracle and/or its affiliates. All rights reserved.

    The contents of this file are subject to the terms of either the GNU
    General Public License Version 2 only ("GPL") or the Common Development
    and Distribution License("CDDL") (collectively, the "License").  You
    may not use this file except in compliance with the License.  You can
    obtain a copy of the License at
    http://glassfish.java.net/public/CDDL+GPL_1_1.html
    or packager/legal/LICENSE.txt.  See the License for the specific
    language governing permissions and limitations under the License.

    When distributing the software, include this License Header Notice in each
    file and include the License file at packager/legal/LICENSE.txt.

    GPL Classpath Exception:
    Oracle designates this particular file as subject to the "Classpath"
    exception as provided by Oracle in the GPL Version 2 section of the License
    file that accompanied this code.

    Modifications:
    If applicable, add the following below the License Header, with the fields
    enclosed by brackets [] replaced by your own identifying information:
    "Portions Copyright [year] [name of copyright owner]"

    Contributor(s):
    If you wish your version of this file to be governed by only the CDDL or
    only the GPL Version 2, indicate your decision by adding "[Contributor]
    elects to include this software in this distribution under the [CDDL or GPL
    Version 2] license."  If you don't indicate a single choice of license, a
    recipient has the option to distribute your version of this file under
    either the CDDL, the GPL Version 2 or to extend the choice of license to
    its licensees as provided above.  However, if you add GPL Version 2 code
    and therefore, elected the GPL Version 2 license, then the option applies
    only if the new code is made subject to such option by the copyright
    holder.

-->
<!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:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd"
         xml:id="filters-and-interceptors">
    <title>Filters and Interceptors</title>
    <section>
        <title>Introduction</title>
        <para>This chapter describes filters, interceptors and their configuration. Filters and interceptors
            can be used on both sides, on the client and the server side. Filters can modify inbound and outbound requests
            and responses including modification of headers, entity and other request/response parameters. Interceptors
            are used primarily for modification of entity input and output streams. You can use interceptors for example
            to zip and unzip output and input entity streams.
        </para>
    </section>


    <section>
        <title>Filters</title>
        <para>
            Filters can be used when you want to modify any request or response parameters like headers. For example
            you would like to add a response header "X-Powered-By" to each generated response. Instead of adding this header
            in each resource method you would use a response filter to add this header.
        </para>
        <para>
            There are filters on the server side and the client side.
        </para>
        <para>
            Server filters:
            <simplelist>
                <member>&jaxrs.container.ContainerRequestFilter;
                </member>
                <member>&jaxrs.container.ContainerResponseFilter;
                </member>
            </simplelist>
            Client filters:
            <simplelist>
                <member>&jaxrs.client.ClientRequestFilter;
                </member>
                <member>&jaxrs.client.ClientResponseFilter;
                </member>
            </simplelist>
        </para>

        <section>
            <title>Server filters</title>
            The following example shows a simple container response filter adding a header to each response.

            <para>
                <example>
                    <title>Container response filter</title>
                    <programlisting language="java" linenumbering="numbered">import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Response;

public class PoweredByResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
        throws IOException {

            responseContext.getHeaders().add("X-Powered-By", "Jersey :-)");
    }
}</programlisting>
                </example>
            </para>


            <para>
                In the example above the <literal>PoweredByResponseFilter</literal>
                always adds a header "X-Powered-By" to the
                response. The filter must inherit from the &jaxrs.container.ContainerResponseFilter; and must be registered
                as a provider. The filter will be executed for every response which is in most cases after the resource method
                is executed. Response filters are executed even if the resource method is not run, for example when
                the resource method is not found and 404 "Not found" response code is returned by the Jersey runtime. In this case
                the filter will be executed and will process the 404 response.
            </para>
            <para>
                The <literal>filter()</literal> method has two arguments, the container request and container response. The
                &jaxrs.ContainerRequestContext; is accessible only for read only purposes as the filter is executed already
                in response phase. The modifications can be done in the &jaxrs.ContainerResponseContext;.
            </para>

            <para>
                The following example shows the usage of a request filter.
            </para>
            <example>
                <title>Container request filter</title>
                <programlisting language="java" linenumbering="numbered">import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;

public class AuthorizationRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext)
                    throws IOException {

        final SecurityContext securityContext =
                    requestContext.getSecurityContext();
        if (securityContext == null ||
                    !securityContext.isUserInRole("privileged")) {

                requestContext.abortWith(Response
                    .status(Response.Status.UNAUTHORIZED)
                    .entity("User cannot access the resource.")
                    .build());
        }
    }
}</programlisting>
            </example>


            <para>
                The request filter is similar to the response filter but does not have access to the ContainerResponseContext
                as no response is accessible yet. Response filter inherits from &jaxrs.container.ContainerResponseFilter;.
                Request filter is executed before the resource method is run and before the
                response is created. The filter has possibility to manipulate the request parameters including request
                headers or entity.
            </para>
            <para>
                The <literal>AuthorizationRequestFilter</literal> in the example checks whether the
                authenticated user is in the privileged role. If it is not then the request is <emphasis>aborted</emphasis>
                by calling <literal>ContainerRequestContext.abortWith(Response response)</literal> method. The method
                is intended to be called from the request filter in situation when the request should not be processed further in the standard processing chain.
                When the <literal>filter</literal> method is finished the response passed as a parameter to the
                <literal>abortWith</literal> method is used to respond to the request. Response filters, if any are registered,
                will be executed and will have possibility to process the aborted response.
            </para>

            <section>
                <title>Pre-matching and post-matching filters</title>
            </section>
            <para>
                All the request filters shown above was implemented as post-matching filters. It means that the filters
                would be applied only after a suitable resource method has been selected to process the actual request
                i.e. after request matching happens. Request matching is the process of finding a resource method that
                should be executed based on the request path and other request parameters. Since post-matching request
                filters are invoked when a particular resource method has already been selected, such filters can not
                influence the resource method matching process.
            </para>
            <para>
                To overcome the above described limitation, there is a possibility to mark
                a server request filter as a <emphasis>pre-matching</emphasis> filter,
                i.e. to annotate the filter class with the &jaxrs.Prematching; annotation.
                Pre-matching filters are request filters that are executed before
                the request matching is started. Thanks to this, pre-matching request filters have
                the possibility to influence which method will be matched. Such a pre-matching request filter example is shown
                here:
            </para>
            <para>
                <example>
                    <title>Pre-matching request filter</title>
                    <programlisting language="java" linenumbering="numbered">...
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
...

@PreMatching
public class PreMatchingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext)
                        throws IOException {
        // change all PUT methods to POST
        if (requestContext.getMethod().equals("PUT")) {
            requestContext.setMethod("POST");
        }
    }
}</programlisting>
                </example>
            </para>
            <para>
                The <literal>PreMatchingFilter</literal> is a simple pre-matching filter which changes all PUT HTTP
                methods to POST. This might be useful when you want to always handle these PUT and POST HTTP methods
                with the same Java code. After the <literal>PreMatchingFilter</literal> has been invoked, the rest
                of the request processing will behave as if the POST HTTP method was originally used.
                You cannot do this in post-matching filters
                (standard filters without &lit.jaxrs.Prematching; annotation)
                as the resource method is already matched (selected). An attempt to tweak the original HTTP method in
                a post-matching filter would cause an <literal>IllegalArgumentException</literal>.
            </para>
            <para>
                As written above, pre-matching filters can fully influence the request matching process, which means
                you can even modify request URI in a pre-matching filter by invoking
                the <literal>setRequestUri(URI)</literal> method of &lit.jaxrs.container.ContainerRequestFilter;
                so that a different resource would be matched.
            </para>
            <para>
                Like in post-matching filters you can abort a response in pre-matching filters too.
            </para>
    </section>
    <section>
        <title>Client filters</title>
            <para>
                Client filters are similar to container filters. The response can also be aborted
                in the &jaxrs.client.ClientRequestFilter; which would cause that no request will actually be sent to the server at all.
                A new response is passed to the <literal>abort</literal> method. This response will be used and delivered
                as a result of the request invocation. Such a response goes through the client response filters.
                This is similar to what happens on the server side. The process is shown in the following example:
            </para>
            <para>
                <example>
                    <title>Client request filter</title>
                    <programlisting language="java" linenumbering="numbered">public class CheckRequestFilter implements ClientRequestFilter {

    @Override
    public void filter(ClientRequestContext requestContext)
                        throws IOException {
        if (requestContext.getHeaders(
                        ).get("Client-Name") == null) {
            requestContext.abortWith(
                        Response.status(Response.Status.BAD_REQUEST)
                .entity("Client-Name header must be defined.")
                        .build());
         }
    }
}</programlisting>
                </example>
            </para>
            <para>
                The <literal>CheckRequestFilter</literal> validates the outgoing request. It is checked for presence of
                a <literal>Client-Name</literal> header. If the header is not present the request will be aborted
                with a made up response with an appropriate code and message in the entity body. This will cause that
                the original request will not be effectively sent to the server but the actual invocation
                will still end up with a response as if it would be generated by the
                server side. If there would be any client response filter it would be executed on this response.
            </para>
            <para>
                To summarize the workflow, for any client request invoked from the client API
                the client request filters (&jaxrs.client.ClientRequestFilter;)
                are executed that could manipulate the request.
                If not aborted, the outcoming request is then physically sent over to the server side
                and once a response is received back from the server the client response
                filters (&jaxrs.client.ClientResponseFilter;)
                are executed that might again manipulate the returned response.
                Finally the response is passed back to the code that invoked the request.
                If the request was aborted in any client request filter then the
                client/server communication is skipped and the aborted response
                is used in the response filters.
            </para>

    </section>
    </section>
    <section>
        <title>Interceptors</title>
        <para>
            Interceptors share a common API for the server and the client side. Whereas filters are primarily intended to manipulate
            request and response parameters like HTTP headers, URIs and/or HTTP methods, interceptors are intended to manipulate entities, via manipulating
            entity input/output streams. If you for example need to encode entity body of a client request then you could
            implement an interceptor to do the work for you.
         </para>
         <para>
            There are two kinds of interceptors, &jaxrs.ReaderInterceptor; and &jaxrs.WriterInterceptor;.
            Reader interceptors are used to manipulate inbound entity streams. These are the streams coming from
            the "wire". So, using a reader interceptor you
            can manipulate request entity stream on the server side (where
            an entity is read from the client request) and response entity stream on the client side (where an entity
            is read from the server response). Writer interceptors are used for cases where entity is written to the
            "wire" which on the server means when writing out a response entity and on the client side when writing
            request entity for a request to be sent out to the server. Writer and reader interceptors are executed before message body
            readers or writers are executed and their primary intention is to wrap the entity streams that will be used in message body
            reader and writers.
        </para>
        <para>
            The following example shows a writer interceptor that enables GZIP compression of the whole entity body.
        </para>
        <para>
            <example>
                <title>GZIP writer interceptor</title>
                <programlisting language="java" linenumbering="numbered">public class GZIPWriterInterceptor implements WriterInterceptor {

    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
                    throws IOException, WebApplicationException {
        final OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new GZIPOutputStream(outputStream));
        context.proceed();
    }
}</programlisting>
            </example>
        </para>
        <para>
            The interceptor gets a output stream from the &jaxrs.WriterInterceptorContext; and sets
            a new one which is a GZIP wrapper of the original output stream. After all interceptors are executed the
            output stream lastly set to the &lit.jaxrs.WriterInterceptorContext; will be used for serialization of the entity. In the
            example above the entity bytes will be written to the GZIPOutputStream which will compress the stream data
            and write them to the original output stream. The original stream is always the stream which writes the data to
            the "wire". When the interceptor is used on the server, the original output stream is the stream into which writes
            data to the underlying server container stream that sends the response to the client.
        </para>
        <para>
            The interceptors wrap the streams and they itself work as wrappers. This means that each interceptor is a wrapper
            of another interceptor and it is responsibility of each interceptor implementation to call the wrapped interceptor.
            This is achieved by calling the <literal>proceed()</literal> method on the &lit.jaxrs.WriterInterceptorContext;.
            This method will call the next registered interceptor in the chain, so effectivelly this will call all remaining registered interceptors. Calling <literal>proceed()</literal> from the last
            interceptor in the chain will call the appropriate message body reader. Therefore every interceptor must call the
            <literal>proceed()</literal> method otherwise the entity would not be written. The wrapping principle is reflected
            also in the method name, aroundWriteTo, which says that the method is wrapping the writing of the entity.
        </para>
        <para>
            The method aroundWriteTo() gets &lit.jaxrs.WriterInterceptorContext; as a parameter. This context contains getters
            and setters for header parameters, request properties, entity, entity stream and other properties. These are the
            properties which will be passed to the final &lit.jaxrs.ext.MessageBodyWriter;. Interceptors are allowed to modify
            all these properties. This could influence writing of an entity by &lit.jaxrs.ext.MessageBodyWriter; and even
            selection of such a writer. By changing media type (&lit.jaxrs.WriterInterceptorContext;.setMediaType())
            the interceptor can cause that different message body writer will be chosen. The interceptor can also
            completely replace the entity if it is needed. However, for modification of headers, request
            properties and such, the filters are usually more preferable choice. Interceptors are executed
            only when there is any entity and when the entity is to be written. So, when you always want to add a new
            header to a response no matter what, use filters as interceptors might not be executed when no entity is
            present. Interceptors should modify properties only for entity serialization
            and deserialization purposes.
        </para>
        <para>
            Let's now look at an example of a &lit.jaxrs.ReaderInterceptor;
        </para>
        <para>
            <example>
                <title>GZIP reader interceptor</title>
                <programlisting language="java" linenumbering="numbered">public class GZIPReaderInterceptor implements ReaderInterceptor {

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context)
                    throws IOException, WebApplicationException {
        final InputStream originalInputStream = context.getInputStream();
        context.setInputStream(new GZIPInputStream(originalInputStream));
        return context.proceed();
    }
}</programlisting>
            </example>
        </para>
        <para>
            The <literal>GZIPReaderInterceptor</literal> wraps the original input stream with the
            <literal>GZIPInputStream</literal>. All further reads from the entity stream will cause that data will be decompressed
            by this stream. The interceptor method <literal>aroundReadFrom()</literal> must return an entity. The entity
            is returned from the <literal>proceed</literal> method of the &jaxrs.ReaderInterceptorContext;. The
            <literal>proceed</literal> method internally calls the wrapped interceptor which must also return an entity.
            The <literal>proceed</literal> method invoked from the last interceptor in the chain calls message body reader which deserializes
            the entity end returns it. Every interceptor can change this entity if there is a need but in the most cases
            interceptors will just return the entity as returned from the <literal>proceed</literal> method.
        </para>
        <para>
            As already mentioned above, interceptors should be primarily used to manipulate entity body.
            Similar to methods exposed by &lit.jaxrs.WriterInterceptorContext; the &lit.jaxrs.ReaderInterceptorContext;
            introduces a set of methods for modification of request/response properties like HTTP headers,
            URIs and/or HTTP methods (excluding getters and setters for entity as entity has not been read yet).
            Again the same rules as for &lit.jaxrs.WriterInterceptor; applies for changing these properties (change only
            properties in order to influence reading of an entity).
        </para>

        </section>
        <section>
            <title>Filter and interceptor execution order</title>
        <para>
            Let's look closer at the context of execution of filters and interceptors. The following steps describes scenario
            where a JAX-RS client makes a POST request to the server. The server receives an entity and sends a response back
            with the same entity. GZIP reader and writer interceptors are registered on the
            client and the server. Also filters are registered on client and server which change the headers of request
            and response.
            <orderedlist>
                <listitem>Client request invoked: The POST request with attached entity is built on the client and invoked.</listitem>
                <listitem>ClientRequestFilters: client request filters are executed on the client and they
                    manipulate the request headers.</listitem>
                <listitem>Client &lit.jaxrs.WriterInterceptor;: As the request contains an entity, writer interceptor registered on the client is executed before
                    a MessageBodyWriter is executed. It wraps the entity output stream with the GZipOutputStream.</listitem>
                <listitem>Client MessageBodyWriter: message body writer is executed on the client which serializes the entity
                    into the new GZipOutput stream. This stream zips the data and sends it to the "wire".</listitem>
                <listitem>Server: server receives a request. Data of entity is compressed which means that pure read from
                    the entity input stream would return compressed data.</listitem>
                <listitem>Server pre-matching ContainerRequestFilters: ContainerRequestFilters are executed that can manipulate
                    resource method matching process.</listitem>
                <listitem>Server: matching: resource method matching is done.</listitem>
                <listitem>Server: post-matching ContainerRequestFilters: ContainerRequestFilters post matching filters are executed.
                    This include execution of all global filters (without name binding) and filters name-bound to the matched
                    method.</listitem>
                <listitem>Server &lit.jaxrs.ReaderInterceptor;: reader interceptors are executed on the server. The GZIPReaderInterceptor
                    wraps the input stream (the stream from the "wire") into the GZipInputStream and set it to context.</listitem>
                <listitem>Server MessageBodyReader: server message body reader is executed and it deserializes the entity
                    from new GZipInputStream (get from the context). This means the reader will read unzipped data and not
                    the compressed data from the "wire".</listitem>
                <listitem>Server resource method is executed: the deserialized entity object is passed to the matched resource
                    method as a parameter. The method returns this entity as a response entity.</listitem>
                <listitem>Server ContainerResponseFilters are executed: response filters are executed on the server and
                    they manipulate the response headers. This include all global bound filters (without name binding) and all filters name-bound to the resource method.</listitem>
                <listitem>Server &lit.jaxrs.WriterInterceptor;: is executed on the server. It wraps the original
                    output stream with a new GZIPOuptutStream. The original stream is the stream that "goes to the wire" (output
                    stream for response from the underlying server container).
                </listitem>
                <listitem>Server MessageBodyWriter: message body writer is executed on the server which serializes the entity
                    into the GZIPOutputStream. This stream compresses the data and writes it to the original stream which sends
                    this compressed data back to the client.
                </listitem>
                <listitem>Client receives the response: the response contains compressed entity data.</listitem>
                <listitem>Client ClientResponseFilters: client response filters are executed and they manipulate the response headers.</listitem>
                <listitem>Client response is returned: the javax.ws.rs.core.Response is returned from the request invocation.</listitem>
                <listitem>Client code calls response.readEntity(): read entity is executed on the client to extract the entity from the response.</listitem>
                <listitem>Client &lit.jaxrs.ReaderInterceptor;: the client reader interceptor is executed when readEntity(Class) is called. The interceptor
                        wraps the entity input stream with GZIPInputStream. This will decompress the data from the original input stream.
                </listitem>
                <listitem>Client MessageBodyReaders: client message body reader is invoked which reads decompressed data from
                    GZIPInputStream and deserializes the entity.</listitem>
                <listitem>Client: The entity is returned from the readEntity().</listitem>
            </orderedlist>
            It is worth to mention that in the scenario above the reader and writer interceptors are invoked only if the
            entity is present (it does not make sense to wrap entity stream when no entity will be written). The same behaviour
            is there for message body readers and writers. As mentioned above, interceptors are executed before
            the message body reader/writer as a part of their execution and they can wrap the input/output stream
            before the entity is read/written. There are exceptions when interceptors are not run before message body
            reader/writers but this is not the case of simple scenario above. This happens for example when the entity is
            read many times from client response using internal buffering. Then the data are intercepted only once and kept
            'decoded' in the buffer.
        </para>

    </section>

    <section>
        <title>Name binding</title>

        <para>
            Filters and interceptors can be <emphasis>name-bound</emphasis>. Name binding is a concept that allows to say to a JAX-RS
            runtime that a specific filter or interceptor will be executed only for a specific resource method. When a filter or
            an interceptor is limited only to a specific resource method we say that it is <emphasis>name-bound</emphasis>.
            Filters and interceptors that do not have such a limitation are called <emphasis>global</emphasis>.
        </para>
        <para>
            Filter or interceptor can be assigned to a resource method using the &jaxrs.NameBinding; annotation. The annotation
            is used as meta annotation for other user implemented annotations that are applied to a providers and resource
            methods. See the following example:
        </para>
        <para>
            <example>
                <title>&lit.jaxrs.NameBinding; example</title>
                <programlisting language="java" linenumbering="numbered">...
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.zip.GZIPInputStream;

import javax.ws.rs.GET;
import javax.ws.rs.NameBinding;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
...


// @Compress annotation is the name binding annotation
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Compress {}


@Path("helloworld")
public class HelloWorldResource {

    @GET
    @Produces("text/plain")
    public String getHello() {
        return "Hello World!";
    }

    @GET
    @Path("too-much-data")
    @Compress
    public String getVeryLongString() {
        String str = ... // very long string
        return str;
    }
}

// interceptor will be executed only when resource methods
// annotated with @Compress annotation will be executed
@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {
    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
                    throws IOException, WebApplicationException {
        final OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new GZIPOutputStream(outputStream));
        context.proceed();
    }
}</programlisting>
            </example>
        </para>
        <para>
            The example above defines a new <literal>@Compress</literal> annotation which is a name binding annotation as
            it is annotated with &lit.jaxrs.NameBinding;. The <literal>@Compress</literal> is applied on the
            resource method <literal>getVeryLongString()</literal> and on the interceptor
            <literal>GZIPWriterInterceptor</literal>. The interceptor will be executed only if any resource method
            with such a annotation will be executed. In our example case the interceptor will be executed only for
            the <literal>getVeryLongString()</literal> method. The interceptor will not be executed for method
            <literal>getHello()</literal>. In this example the reason is probably clear. We would like to compress
            only long data and we do not need to compress the short response of "Hello World!".
        </para>
        <para>
            Name binding can be applied on a resource class. In the example <literal>HelloWorldResource</literal>
            would be annotated with <literal>@Compress</literal>. This would mean that all resource
            methods will use compression in this case.
        </para>
        <para>
            There might be many name binding annotations defined in an application. When any provider (filter
            or interceptor) is annotated with more than one name binding annotation, then it will be executed for
            resource methods which contain ALL these annotations. So, for example if our interceptor would be
            annotated with another name binding annotation @GZIP then the resource method would need to have both annotations attached,
            @Compress and @GZIP, otherwise the interceptor would not be executed. Based on the previous paragraph we can
            even use the combination when the
            resource method <literal>getVeryLongString()</literal> would be annotated with @Compress and resource class
            <literal>HelloWorldResource</literal> would be annotated from with @GZIP. This would also trigger the interceptor as
            annotations of resource methods are aggregated from resource method and from resource class. But this is probably
            just an edge case which will not be used so often.
        </para>
        <para>
            Note that <emphasis>global filters are executed always</emphasis>, so even for resource methods
            which have any name binding annotations.
        </para>
    </section>
    <section>
        <title>Dynamic binding</title>
        <para>Dynamic binding is a way how to assign filters and interceptors to the resource methods in a dynamic
        manner. Name binding from the previous chapter uses a static approach and changes to binding require source
        code change and recompilation. With dynamic binding you can implement code which defines bindings during the application
        initialization time. The following example shows how to implement dynamic binding.</para>



        <para>
            <example>
                <title>Dynamic binding example</title>
                <programlisting language="java" linenumbering="numbered">...
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.container.DynamicFeature;
...

@Path("helloworld")
public class HelloWorldResource {

    @GET
    @Produces("text/plain")
    public String getHello() {
        return "Hello World!";
    }

    @GET
    @Path("too-much-data")
    public String getVeryLongString() {
        String str = ... // very long string
        return str;
    }
}

// This dynamic binding provider registers GZIPWriterInterceptor
// only for HelloWorldResource and methods that contain
// "VeryLongString" in their name. It will be executed during
// application initialization phase.
public class CompressionDynamicBinding implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        if (HelloWorldResource.class.equals(resourceInfo.getResourceClass())
                &amp;&amp; resourceInfo.getResourceMethod()
                    .getName().contains("VeryLongString")) {
            context.register(GZIPWriterInterceptor.class);
        }
    }
}</programlisting>
            </example>
        </para>

        <para>
            The example contains one <literal>HelloWorldResource</literal> which is known from the previous name binding example.
            The difference is in the <literal>getVeryLongString</literal> method, which now does not define
            the <literal>@Compress</literal> name binding annotations. The binding is done
            using the provider which implements &jaxrs.container.DynamicFeature; interface. The interface defines
            one <literal>configure</literal>
            method with two arguments, <literal>ResourceInfo</literal> and <literal>FeatureContext</literal>.
            <literal>ResourceInfo</literal> contains information about the resource and method to which the binding can be done.
            The <literal>configure</literal> method will be executed once for each resource method that is defined in the application.
            In the example above the provider will be executed twice, once for the <literal>getHello()</literal> method
            and once for <literal>getVeryLongString()</literal> (
            once the resourceInfo will contain information about getHello() method and once it will point to
            getVeryLongString()). If a dynamic binding provider wants to register any provider for the actual resource method
            it will do that using provided <literal>FeatureContext</literal> which extends
            JAX-RS <literal>Configurable</literal> API. All methods for registration of filter or interceptor classes or instances can be used.
            Such dynamically registered filters or interceptors will be bound only to the actual resource method. In the example above the
            <literal>GZIPWriterInterceptor</literal> will be bound only to the method <literal>getVeryLongString()</literal>
            which will cause that data will be compressed only for this method and not for the method
            <literal>getHello()</literal>. The code of <literal>GZIPWriterInterceptor</literal> is in the examples above.
        </para>
        <para>
            Note that filters and interceptors registered using dynamic binding are only additional filters run for the
            resource method. If there are any name bound providers or global providers they will still be executed.
        </para>
    </section>

    <section>
        <title>Priorities</title>

        <para>In case you register more filters and interceptors you might want to define an exact order in which
            they should be invoked. The order can be controlled by the <literal>@Priority</literal> annotation defined
            by the <literal>javax.annotation.Priority</literal> class. The annotation accepts an integer parameter of priority.
            Providers used in request processing (&lit.jaxrs.container.ContainerRequestFilter;,
            &lit.jaxrs.client.ClientRequestFilter;) as well as entity interceptors (&lit.jaxrs.ReaderInterceptor;,
            &lit.jaxrs.WriterInterceptor;) are sorted based on the priority in an ascending manner. So, a request filter with
            priority defined with <literal>@Priority(1000)</literal>
            will be executed before another request filter with priority  defined as <literal>@Priority(2000)</literal>. Providers
            used during response processing (&lit.jaxrs.container.ContainerResponseFilter;,
            &lit.jaxrs.client.ClientResponseFilter;) are executed
            in the reverse order (using descending manner), so a provider with the priority defined with
            <literal>@Priority(2000)</literal> will be executed before another provider with
             priority defined with <literal>@Priority(1000)</literal>.
        </para>
        <para>
            It's a good practice to assign a priority to filters and interceptors. Use &jaxrs.Priorities; class which
            defines standardized priorities in JAX-RS for different usages, rather than inventing your
            own priorities. So, when you for example write an authentication filter you would assign a priority 1000 which
            is the value of &lit.jaxrs.Priorities;<literal>.AUTHENTICATION</literal>. The following example
            shows the filter from the beginning
            of this chapter with a priority assigned.
        </para>

        <para>
            <example>
                <title>Priorities example</title>
                <programlisting language="java" linenumbering="numbered">...
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
...

@Priority(Priorities.HEADER_DECORATOR)
public class ResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext,
                    ContainerResponseContext responseContext)
                    throws IOException {

        responseContext.getHeaders().add("X-Powered-By", "Jersey :-)");
    }
}</programlisting>
            </example>
        </para>
        <para>
            As this is a response filter and response filters are executed in the reverse order,
            any other filter with priority lower than 3000 (<literal>Priorities.HEADER_DECORATOR</literal> is 3000) will be executed after
            this filter. So, for example <literal>AUTHENTICATION</literal> filter (priority 1000) would be run after this filter.
        </para>
    </section>
</chapter>
