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

    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

    Copyright (c) 2012-2013 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: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="message-body-workers">
    <title>JAX-RS Entity Providers</title>
    <section>
        <title>Introduction</title>
        <para>
            Entity payload, if present in an received HTTP message, is passed to Jersey from an I/O container as an input stream.
            The stream may, for example, contain data represented as a plain text, XML or JSON document. However, in many JAX-RS
            components that process these inbound data, such as resource methods or client responses, the JAX-RS API user can
            access the inbound entity as an arbitrary Java object that is created from the content of the input stream based on
            the representation type information. For example, an entity created from an input stream that contains data
            represented as a XML document, can be converted to a custom JAXB bean.
            Similar concept is supported for the outbound entities. An entity returned from the resource method in the form
            of an arbitrary Java object can be serialized by Jersey into a container output stream as a specified representation.
            Of course, while JAX-RS implementations do provide default support for most common combinations of Java type and it's
            respective on-the-wire representation formats, JAX-RS implementations do not support the conversion described above
            for any arbitrary Java type and any arbitrary representation format by default. Instead, a generic extension concept
            is exposed in JAX-RS API to allow application-level customizations of this JAX-RS runtime to support for entity
            conversions. The JAX-RS extension API components that provide the user-level extensibility are typically referred to
            by several terms with the same meaning, such as <emphasis>entity providers</emphasis>,
            <emphasis>message body providers</emphasis>, <emphasis>message body workers</emphasis> or
            <emphasis>message body readers and writers</emphasis>. You may find all these terms used interchangeably throughout
            the user guide and they all refer to the same concept.
        </para>
        <para>
            In JAX-RS extension API (or SPI - service provider interface, if you like) the concept is captured in 2 interfaces.
            One for handling inbound entity representation-to-Java de-serialization - &jaxrs.ext.MessageBodyReader; and the other
            one for handling the outbound entity Java-to-representation serialization - &jaxrs.ext.MessageBodyWriter;.
            A &lit.jaxrs.ext.MessageBodyReader;, as the name suggests, is an extension that supports reading the message body
            representation from an input stream and converting the data into an instance of a specific Java type.
            A &lit.jaxrs.ext.MessageBodyWriter; is then responsible for converting a message payload from an instance of a
            specific Java type into a specific representation format that is sent over the wire to the other party as part of an
            HTTP message exchange.
            Both of these providers can be used to provide message payload serialization and de-serialization support on the
            server as well as the client side. A message body reader or writer is always used whenever a HTTP request or
            response contains an entity and the entity is either requested by the application code (e.g. injected as a parameter
            of JAX-RS resource method or a response entity read on the client from a &jaxrs.core.Response;) or has to be
            serialized and sent to the other party (e.g. an instance returned from a JAX-RS resource method or a request
            entity sent by a JAX-RS client).
        </para>
    </section>
    <section>
        <title>How to Write Custom Entity Providers</title>
        <para>
            A best way how to learn about entity providers is to walk through an example of writing one. Therefore we will
            describe here the process of implementing a custom &jaxrs.ext.MessageBodyWriter; and
            &jaxrs.ext.MessageBodyReader; using a practical example. Let's first setup the stage by defining a JAX-RS
            resource class for the server side story of our application.

            <example>
                <title>Example resource class</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
public class MyResource {
    @GET
    @Produces("application/xml")
    public MyBean getMyBean() {
        return new MyBean("Hello World!", 42);
    }

    @POST
    @Consumes("application/xml")
    public String postMyBean(MyBean myBean) {
        return myBean.anyString;
    }
}</programlisting>
            </example>

            The resource class defines &lit.http.GET; and &lit.http.POST; resource methods. Both methods work with an entity
            that is an instance of <literal>MyBean</literal>.
        </para>
        <para>
            The <literal>MyBean</literal> class is defined in the next example:

            <example>
                <title>MyBean entity class</title>
                <programlisting language="java" linenumbering="numbered">@XmlRootElement
public class MyBean {
    @XmlElement
    public String anyString;
    @XmlElement
    public int anyNumber;

    public MyBean(String anyString, int anyNumber) {
        this.anyString = anyString;
        this.anyNumber = anyNumber;
    }

    // empty constructor needed for deserialization by JAXB
    public MyBean() {
    }

    @Override
    public String toString() {
        return "MyBean{" +
            "anyString='" + anyString + '\'' +
            ", anyNumber=" + anyNumber +
            '}';
    }
}</programlisting>
            </example>
        </para>
        <section>
            <title>MessageBodyWriter</title>
            <para>
                The <literal>MyBean</literal> is a JAXB-annotated POJO. In &lit.http.GET; resource method we return
                the instance of MyBean and we would like Jersey runtime to serialize it into XML and write
                it as an entity body to the response output stream. We design a custom &lit.jaxrs.ext.MessageBodyWriter;
                that can serialize this POJO into XML. See the following code sample:

                <note>
                    <para>
                        Please note, that this is only a demonstration of how to write a custom entity provider.
                        Jersey already contains default support for entity providers that can serialize JAXB beans
                        into XML.
                    </para>
                </note>

                <example>
                    <title>MessageBodyWriter example</title>
                    <programlisting language="java" linenumbering="numbered"><![CDATA[@Produces("application/xml")
public class MyBeanMessageBodyWriter implements MessageBodyWriter<MyBean> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
                               Annotation[] annotations, MediaType mediaType) {
        return type == MyBean.class;
    }

    @Override
    public long getSize(MyBean myBean, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        // deprecated by JAX-RS 2.0 and ignored by Jersey runtime
        return 0;
    }

    @Override
    public void writeTo(MyBean myBean,
                        Class<?> type,
                        Type genericType,
                        Annotation[] annotations,
                        MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders,
                        OutputStream entityStream)
                        throws IOException, WebApplicationException {

        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(MyBean.class);

            // serialize the entity myBean to the entity output stream
            jaxbContext.createMarshaller().marshal(myBean, entityStream);
        } catch (JAXBException jaxbException) {
            throw new ProcessingException(
                "Error serializing a MyBean to the output stream", jaxbException);
        }
    }
}]]></programlisting>
                </example>
            </para>
            <para>
                The <literal>MyBeanMessageBodyWriter</literal> implements the &lit.jaxrs.ext.MessageBodyWriter;
                interface that contains three methods. In the next sections we'll explore these methods more closely.
            </para>
            <section>
                <title>
                    <literal>MessageBodyWriter.isWriteable</literal>
                </title>
                <para>
                    A method <literal>isWriteable</literal>
                    should return true if the &lit.jaxrs.ext.MessageBodyWriter; is able to write the given type. Method
                    does not decide only based on the Java type of the entity but also on annotations attached to the entity
                    and the requested representation media type.
                </para>
                <para>
                    Parameters <literal>type</literal> and <literal>genericType</literal> both define the entity,
                    where <literal>type</literal> is a raw Java type
                    (for example, a <literal>java.util.List</literal> class) and <literal>genericType</literal> is a
                    &jdk6.ParameterizedType; including generic information (for example <literal>List&lt;String&gt;</literal>).
                </para>
                <para>
                    Parameter <literal>annotations</literal> contains annotations that are either attached to the resource
                    method and/or annotations that are attached to the entity by building response like in the following piece
                    of code:

                    <example>
                        <title>Example of assignment of annotations to a response entity</title>
                        <programlisting language="java" linenumbering="numbered">@Path("resource")
public static class AnnotatedResource {

    @GET
    public Response get() {
        Annotation annotation = AnnotatedResource.class
                            .getAnnotation(Path.class);
        return Response.ok()
                .entity("Entity", new Annotation[] {annotation}).build();
    }
}</programlisting>
                    </example>

                    In the example above, the &lit.jaxrs.ext.MessageBodyWriter; would get
                    <literal>annotations</literal> parameter containing a JAX-RS <literal>@GET</literal> annotation
                    as it annotates the resource method and also a <literal>@Path</literal> annotation as it
                    is passed in the response (but not because it annotates the resource; only resource
                    method annotations are included). In the case of <literal>MyResource</literal>
                    and method <literal>getMyBean</literal> the annotations would contain the
                    &jaxrs.GET; and the &jaxrs.Produces; annotation.
                </para>
                <para>
                    The last parameter of the <literal>isWriteable</literal> method is the <literal>mediaType</literal>
                    which is the media type attached to the response entity by annotating the resource method with a
                    &lit.jaxrs.Produces; annotation or the request media type specified in the JAX-RS Client API.
                    In our example, the media type passed to providers for the resource <literal>MyResource</literal> and method
                    <literal>getMyBean</literal> would be <literal>"application/xml"</literal>.
                </para>
                <para>
                    In our implementation of the <literal>isWriteable</literal> method, we
                    just check that the type is <literal>MyBean</literal>. Please note, that
                    this method might be executed multiple times by Jersey runtime as Jersey needs to check
                    whether this provider can be used for a particular combination of entity Java type, media type, and attached
                    annotations, which may be potentially a performance hog. You can limit the number of execution by
                    properly defining the &lit.jaxrs.Produces; annotation on the &lit.jaxrs.ext.MessageBodyWriter;.
                    In our case thanks to &lit.jaxrs.Produces; annotation, the provider will be considered
                    as writeable (and the method <literal>isWriteable</literal> might be executed) only if the
                    media type of the outbound message is <literal>"application/xml"</literal>. Additionally, the provider
                    will only be considered as possible candidate and its <literal>isWriteable</literal> method will
                    be executed, if the generic type of the provider is either a sub class or super class of
                    <literal>type</literal> parameter.
                </para>
            </section>
        <section>
            <title>
                <literal>MessageBodyWriter.writeTo</literal>
            </title>
            <para>
                Once a message body writer is selected as the most appropriate (see the <xref linkend="providers-selection" />
                for more details on entity provider selection), its <literal>writeTo</literal> method is invoked. This method
                receives parameters with the same meaning as in <literal>isWriteable</literal> as well as a few additional ones.
            </para>
            <para>
                In addition to the parameters already introduced, the <literal>writeTo</literal> method defies also
                <literal>httpHeaders</literal> parameter, that contains HTTP headers associated with the
                outbound message.

                <note>
                    <para>
                        When a &lit.jaxrs.ext.MessageBodyWriter; is invoked, the headers still can be modified in this point
                        and any modification will be reflected in the outbound HTTP message being sent. The modification of
                        headers must however happen before a first byte is written to the supplied output stream.
                    </para>
                </note>
            </para>
            <para>
                Another new parameter, <literal>myBean</literal>, contains the entity instance to be serialized (the type of
                entity corresponds to generic type of &lit.jaxrs.ext.MessageBodyWriter;). Related parameter
                <literal>entityStream</literal> contains the entity output stream to which the method should serialize the entity.
                In our case we use JAXB to marshall the entity into the <literal>entityStream</literal>. Note, that the
                <literal>entityStream</literal> is not closed at the end of method; the stream will be closed by Jersey.
                <important>
                    <para>
                        Do not close the entity output stream in the <literal>writeTo</literal> method of your
                        &lit.jaxrs.ext.MessageBodyWriter; implementation.
                    </para>
                </important>
            </para>
        </section>

        <section>
            <title>
                <literal>MessageBodyWriter.getSize</literal>
            </title>
            <para>
                The method is deprecated since JAX-RS 2.0 and Jersey 2 ignores the return value. In JAX-RS 1.0 the
                method could return the size of the entity that would be then used for "Content-Length" response
                header. In Jersey 2.0 the "Content-Length" parameter is computed automatically using an internal
                outbound entity buffering. For details about configuration options of outbound entity buffering see the javadoc
                of &jersey.message.MessageProperties;, property <literal>OUTBOUND_CONTENT_LENGTH_BUFFER</literal>
                which configures the size of the buffer.
                <note>
                    <para>
                        You can disable the Jersey outbound entity buffering by setting the buffer size to 0.
                    </para>
                </note>
            </para>
        </section>
        <section>
            <title>Testing a &lit.jaxrs.ext.MessageBodyWriter;</title>
            <para>
                Before testing the <literal>MyBeanMessageBodyWriter</literal>, the writer must
                be registered as a custom JAX-RS extension provider. It should either be added to your application
                &jersey.server.ResourceConfig;, or returned from your custom &jaxrs.core.Application; sub-class, or
                annotated with &jaxrs.ext.Provider; annotation to leverage JAX-RS provider auto-discovery feature.
            </para>
            <para>
                After registering the <literal>MyBeanMessageBodyWriter</literal> and <literal>MyResource</literal> class
                in our application, the request can be initiated (in this example from Client API).

                <example xml:id="client-get-call">
                    <title>Client code testing MyBeanMessageBodyWriter</title>
                    <programlisting language="java" linenumbering="numbered" >WebTarget webTarget = // initialize web target to the context root
            // of example application
Response response = webTarget.path("resource")
                        .request(MediaType.APPLICATION_XML).get();
System.out.println(response.getStatus());
String myBeanXml = response.readEntity(String.class);
System.out.println(myBeanXml);</programlisting>
                </example>

                The client code initiates the &lit.http.GET; which will be matched to the resource method
                <literal>MyResource.getMyBean()</literal>. The response entity is de-serialized as a <literal>String</literal>.
            </para>
            <para>
                The result of console output is:

                <example>
                    <title>Result of MyBeanMessageBodyWriter test</title>
                    <screen language="text" linenumbering="unnumbered"><![CDATA[200
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><myBean>
<anyString>Hello World!</anyString><anyNumber>42</anyNumber></myBean>]]></screen>
                </example>

                The returned status is 200 and the entity is stored in the response in a <literal>XML</literal> format.
                Next, we will look at how the Jersey de-serializes this XML document into a <literal>MyBean</literal> consumed by
                our &lit.http.POST; resource method.
            </para>
        </section>
    </section>
        <section>
            <title>MessageBodyReader</title>
            <para>
                In order to de-serialize the entity of <literal>MyBean</literal> on the server or the client, we need to implement
                a custom &jaxrs.ext.MessageBodyReader;.
                <note>
                    <para>
                        Please note, that this is only a demonstration of how to write a custom entity provider.
                        Jersey already contains default support for entity providers that can serialize JAXB beans
                        into XML.
                    </para>
                </note>
            </para>
            <para>
                Our &lit.jaxrs.ext.MessageBodyReader; implementation is listed in <xref linkend="mbw.ex.mbr" />.

                <example xml:id="mbw.ex.mbr">
                    <title>MessageBodyReader example</title>
                    <programlisting language="java" linenumbering="numbered"><![CDATA[public static class MyBeanMessageBodyReader
        implements MessageBodyReader<MyBean> {

@Override
public boolean isReadable(Class<?> type, Type genericType,
    Annotation[] annotations, MediaType mediaType) {
    return type == MyBean.class;
}

@Override
public MyBean readFrom(Class<MyBean> type,
    Type genericType,
    Annotation[] annotations, MediaType mediaType,
    MultivaluedMap<String, String> httpHeaders,
    InputStream entityStream)
        throws IOException, WebApplicationException {

    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(MyBean.class);
        MyBean myBean = (MyBean) jaxbContext.createUnmarshaller()
            .unmarshal(entityStream);
        return myBean;
    } catch (JAXBException jaxbException) {
        throw new ProcessingException("Error deserializing a MyBean.",
            jaxbException);
    }
}
}]]></programlisting>
                </example>

                It is obvious that the &lit.jaxrs.ext.MessageBodyReader; interface is similar to &lit.jaxrs.ext.MessageBodyWriter;.
                In the next couple of sections we will explore it's API methods.
            </para>
            <section>
                <title><literal>MessageBodyReader.isReadable</literal></title>
                <para>
                    It defines the method <literal>isReadable()</literal> which has a very simliar meaning as method
                    <literal>isWriteable()</literal> in &lit.jaxrs.ext.MessageBodyWriter;. The method returns &lit.true;
                    if it is able to de-serialize the given type. The <literal>annotations</literal> parameter contains annotations
                    that are attached to the entity parameter in the resource method. In our &lit.http.POST; resource
                    method <literal>postMyBean</literal> the entity parameter <literal>myBean</literal> is not
                    annotated, therefore no annotation will be passed to the isReadable. The <literal>mediaType</literal>
                    parameter contains the entity media type. The media type, in our case, must be consumable by the &lit.http.POST;
                    resource method, which is specified by placing a JAX-RS &jaxrs.Consumes; annotation to the method.
                    The resource method <literal>postMyBean()</literal> is annotated with
                    <literal>@Consumes("application/xml")</literal>,
                    therefore for purpose of de-serialization of entity for the <literal>postMyBean()</literal> method,
                    only requests with entities represented as <literal>"application/xml"</literal>
                    media type will match the method. However, this method might be executed for for entity types that are sub classes
                    or super classes of the declared generic type on the &lit.jaxrs.ext.MessageBodyReader; will be also considered.
                    It is a responsibility of the <literal>isReadable</literal> method to decide whether it is able
                    to de-serialize the entity and type comparison is one of the basic decision steps.
                    <tip>
                        <para>
                            In order to reduce number of <literal>isReadable</literal> executions, always define correctly the consumable
                            media type(s) with the &lit.jaxrs.Consumes; annotation on your custom &lit.jaxrs.ext.MessageBodyReader;.
                        </para>
                    </tip>
                </para>
            </section>
            <section>
                <title><literal>MessageBodyReader.readFrom</literal></title>
                <para>
                    The <literal>readForm()</literal> method gets the parameters with the same meaning as in
                    <literal>isReadable()</literal>. The additional <literal>entityStream</literal> parameter provides a handle
                    to the entity input stream from which the entity bytes should be read and de-serialized into a Java entity which
                    is then returned from the method. Our <literal>MyBeanMessageBodyReader</literal> de-serializes the incoming
                    XML data into an instance of <literal>MyBean</literal> using JAXB.

                    <important>
                        <para>
                            Do not close the entity input stream in your &lit.jaxrs.ext.MessageBodyReader; implementation. The stream
                            will be automatically closed by Jersey runtime.
                        </para>
                    </important>
                </para>
            </section>
            <section>
                <title>Testing a &lit.jaxrs.ext.MessageBodyWriter;</title>

                <para>
                    Now let's send a test request using the JAX-RS Client API.

                    <example>
                        <title>Testing MyBeanMessageBodyReader</title>
                        <programlisting language="java" linenumbering="numbered"><![CDATA[final MyBean myBean = new MyBean("posted MyBean", 11);
Response response = webTarget.path("resource").request("application/xml")
        .post(Entity.entity(myBean, "application/xml"));

System.out.println(response.getStatus());
final String responseEntity = response.readEntity(String.class);
System.out.println(responseEntity);
]]></programlisting>
                    </example>
                </para>
                <para>
                    The console output is:

                    <example>
                        <title>Result of testing MyBeanMessageBodyReader</title>
                        <screen language="text" linenumbering="unnumbered"><![CDATA[200
posted MyBean]]></screen>
                    </example>
                </para>
            </section>
            <section>
                <title>Using Entity Providers with JAX-RS Client API</title>
                <para>
                    Both, &lit.jaxrs.ext.MessageBodyReader; and &lit.jaxrs.ext.MessageBodyWriter; can be registered in a
                    configuration of JAX-RS Client API components typically without any need to change their code. The example
                    <xref linkend="mbw.ex.client.mbr.reg" /> is a variation on the <xref linkend="client-get-call" />
                    listed in one of the previous sections.

                    <example xml:id="mbw.ex.client.mbr.reg">
                        <title>MessageBodyReader registered on a JAX-RS client</title>

                        <programlisting language="java" linenumbering="numbered"><![CDATA[Client client = ClientBuilder.newBuilder()
    .register(MyBeanMessageBodyReader.class).build();

Response response = client.target("http://example/comm/resource")
    .request(MediaType.APPLICATION_XML).get();
System.out.println(response.getStatus());
MyBean myBean = response.readEntity(MyBean.class);
System.out.println(myBean);]]></programlisting>
                    </example>
                </para>
                <para>
                    The code above registers <literal>MyBeanMessageBodyReader</literal> to the &jaxrs.client.Client; configuration
                    using a &jaxrs.client.ClientBuilder; which means that the provider will be used for any &jaxrs.client.WebTarget;
                    produced by the <literal>client</literal> instance.
                    <note>
                        <para>
                            You could also register the JAX-RS entity (and any other) providers to individual
                            &lit.jaxrs.client.WebTarget; instances produced by the client.
                        </para>
                    </note>

                    Then, using the fluent chain of method invocations, a resource target pointing to our
                    <literal>MyResource</literal> is defined, a HTTP &lit.http.GET; request is invoked.
                    The response entity is then read as an instance of a <literal>MyBean</literal> type by invoking the
                    <literal>response.readEntity</literal> method, that internally locates the registered
                    <literal>MyBeanMessageBodyReader</literal> and uses it for entity de-serialization.
                </para>
                <para>
                    The console output for the example is:
                    <example>
                        <title>Result of client code execution</title>
                        <screen language="text" linenumbering="unnumbered"><![CDATA[200
MyBean{anyString='Hello World!', anyNumber=42}]]></screen>
                    </example>
                </para>
            </section>
        </section>
    </section>

    <section xml:id="providers-selection">
        <title>Entity Provider Selection</title>

        <para>
            Usually there are many entity providers registered on the server or client side (be default there must be
            at least providers mandated by the JAX-RS specification, such as providers for primitive types, byte array,
            JAXB beans, etc.).
            JAX-RS defines an algorithm for selecting the most suitable provider for entity processing. This algorithm
            works with information such as entity Java type and on-the-wire media type representation of entity, and searches
            for the most suitable entity provider from the list of available providers based on the supported media type
            declared on each provider (defined by &lit.jaxrs.Produces; or &lit.jaxrs.Consumes; on the provider class)
            as well as based on the generic type declaration of the available providers. When a list of suitable candidate
            entity providers is selected and sorted based on the rules defined in JAX-RS specification, a JAX-RS runtime
            then it invokes <literal>isReadable</literal> or <literal>isWriteable</literal> method respectively on each
            provider in the list until a first provider is found that returns &lit.true;. This provider is then used to
            process the entity.
        </para>
        <para>
            The following steps describe the algorithm for selecting a &lit.jaxrs.ext.MessageBodyWriter; (extracted
            from JAX-RS with little modifications). The steps refer to the previously discussed example application.
            The &lit.jaxrs.ext.MessageBodyWriter; is searched for purpose of deserialization of <literal>MyBean</literal>
            entity returned from the method <literal>getMyBean</literal>. So, <emphasis>type is <literal>MyBean</literal>
            and media type <literal>"application/xml"</literal></emphasis>. Let's assume the runtime contains also
            registered providers, namely:

            <simplelist>
                <member>
                    <literal>A</literal>: <literal>@Produces("application/*")</literal> with generic type
                    <literal>&lt;Object&gt;</literal>
                </member>
                <member>
                    <literal>B</literal>: <literal>@Produces("*/*")</literal> with generic type <literal>&lt;MyBean&gt;</literal>
                </member>
                <member>
                    <literal>C</literal>: <literal>@Produces("text/plain")</literal> with generic type
                    <literal>&lt;MyBean&gt;</literal>
                </member>
                <member>
                    <literal>D</literal>: <literal>@Produces("application/xml")</literal> with generic type
                    <literal>&lt;Object&gt;</literal>
                </member>
                <member>
                    <literal>MyBeanMessageBodyWriter</literal>: <literal>@Produces("application/xml")</literal> with generic
                    type <literal>&lt;MyBean&gt;</literal>
                </member>
            </simplelist>
        </para>
        <para>
            The algorithm executed by a JAX-RS runtime to select a proper &lit.jaxrs.ext.MessageBodyWriter; implementation
            is illustrated in <xref linkend="mbw.writer.selection.algorithm" />.
        </para>
        <procedure xml:id="mbw.writer.selection.algorithm">
            <title>&lit.jaxrs.ext.MessageBodyWriter; Selection Algorithm</title>
            <step>
                <para>
                    Obtain the object that will be mapped to the message entity body. For a return type of Response
                    or subclasses, the object is the value of the entity property, for other return types it is the returned
                    object.
                </para>
                <para>
                    So in our case, for the resource method <literal>getMyBean</literal> the type will
                    be <literal>MyBean</literal>.
                </para>
            </step>
            <step>
                <para>
                    Determine the media type of the response.
                </para>
                <para>
                    In our case. for resource method <literal>getMyBean</literal>
                    annotated with <literal>@Produces("application/xml")</literal>, the media type will be
                    <literal>"application/xml"</literal>.
                </para>
            </step>
            <step>
                <para>
                    Select the set of MessageBodyWriter providers that support the object and media
                    type of the message entity body.
                </para>
                <para>
                    In our case, for entity media type <literal>"application/xml"</literal>
                    and type <literal>MyBean</literal>, the appropriate &lit.jaxrs.ext.MessageBodyWriter; will
                    be the <literal>A</literal>, <literal>B</literal>, <literal>D</literal>
                    and <literal>MyBeanMessageBodyWriter</literal>. The provider <literal>C</literal> does
                    not define the appropriate
                    media type. <literal>A</literal> and <literal>B</literal> are fine as
                    their type is more generic and compatible with <literal>"application/xml"</literal>.
                </para>
            </step>
            <step xml:id="mbw.writer.selection.algorithm.sortStep">
                <para>
                    Sort the selected MessageBodyWriter providers with a primary key of generic type where providers
                    whose generic type is the nearest superclass of the object class are sorted first and a secondary key of
                    media type. Additionally, JAX-RS specification mandates that custom, user registered providers have to
                    be sorted ahead of default providers provided by JAX-RS implementation. This is used as a tertiary
                    comparison key. User providers are places prior to Jersey internal providers in to the final ordered list.
                </para>
                <para>
                    The sorted providers will be: <literal>MyBeanMessageBodyWriter</literal>,
                    <literal>B</literal>. <literal>D</literal>, <literal>A</literal>.
                </para>
            </step>
            <step>
                <para>
                    Iterate through the sorted &lit.jaxrs.ext.MessageBodyWriter; providers and, utilizing the
                    <literal>isWriteable</literal> method of each until you find a &lit.jaxrs.ext.MessageBodyWriter; that
                    returns &lit.true;.
                </para>
                <para>
                    The first provider in the list - our <literal>MyBeanMessageBodyWriter</literal> returns &lit.true; as
                    it compares types and the types matches. If it would return &lit.false;, the next provider
                    <literal>B</literal> would by check by invoking its <literal>isWriteable</literal> method.
                </para>
            </step>
            <step>
                <para>
                    If step 5 locates a suitable &lit.jaxrs.ext.MessageBodyWriter; then use its writeTo method to map the
                    object to the entity body.
                </para>
                <para>
                    <literal>MyBeanMessageBodyWriter.writeTo</literal> will be executed and it will serialize the
                    entity.
                </para>
                <stepalternatives>
                    <step>
                        <para>
                            Otherwise, the server runtime MUST generate a generate an
                            <literal>InternalServerErrorException</literal>, a subclass of
                            <literal>WebApplicationException</literal> with its status set to 500, and no entity and the client
                            runtime MUST generate a <literal>ProcessingException</literal>.
                        </para>
                        <para>
                            We have successfully found a provider, thus no exception is generated.
                        </para>
                    </step>
                </stepalternatives>
            </step>
        </procedure>
        <note>
            <para>
                JAX-RS 2.0 is incompatible with JAX-RS 1.x in one step of the entity provider selection algorithm.
                JAX-RS 1.x defines sorting keys priorities in the <xref linkend="mbw.writer.selection.algorithm.sortStep" />
                in exactly opposite order. So, in JAX-RS 1.x the keys are defined in the order: primary media type,
                secondary type declaration distance where custom providers have always precedence to internal providers.
                If you want to force Jersey to use the algorithm compatible with JAX-RS 1.x, setup the property
                (to &jersey.server.ResourceConfig; or return from &jaxrs.core.Application; from its
                <literal>getProperties</literal> method):

                <programlisting language="java" linenumbering="unnumbered"><![CDATA[jersey.config.workers.legacyOrdering=true]]></programlisting>

                Documentation of this property can be found in the javadoc of &jersey.message.MessageProperties;.
            </para>
        </note>

        <para>
            The algorithm for selection of &lit.jaxrs.ext.MessageBodyReader; is similar, including the incompatibility
            between JAX-RS 2.0 and JAX-RS 1.x and the property to workaround it. The algorithm is defined as follows:
        </para>
        <procedure xml:id="mbw.reader.selection.algorithm">
            <title>&lit.jaxrs.ext.MessageBodyReader; Selection Algorithm</title>
            <step>
                <para>
                    Obtain the media type of the request. If the request does not contain a <literal>Content-Type</literal>
                    header then use <literal>application/octet-stream</literal> media type.
                </para>
            </step>
            <step>
                <para>
                    Identify the Java type of the parameter whose value will be mapped from the entity body. The
                    Java type on the server is the type of the entity parameter of the resource method. On the client
                    it is the <literal>Class</literal> passed to <literal>readFrom</literal> method.
                </para>
            </step>
            <step>
                <para>
                    Select the set of available &lit.jaxrs.ext.MessageBodyReader; providers that support the media type
                    of the request.
                </para>
            </step>
            <step xml:id="mbw.reader.selection.algorithm.selectStep">
                <para>
                    Iterate through the selected &lit.jaxrs.ext.MessageBodyReader; classes and, utilizing their
                    <literal>isReadable</literal> method, choose the first &lit.jaxrs.ext.MessageBodyReader; provider that
                    supports the desired combination of Java type/media type/annotations parameters.
                </para>
            </step>
            <step>
                <para>
                    If <xref linkend="mbw.reader.selection.algorithm.selectStep" /> locates a suitable
                    &lit.jaxrs.ext.MessageBodyReader;, then use its <literal>readFrom</literal> method to map the entity
                    body to the desired Java type.
                </para>
                <stepalternatives>
                    <step>
                        <para>
                            Otherwise, the server runtime MUST generate a <literal>NotSupportedException</literal>
                            (HTTP 415 status code) and no entity and the client runtime MUST generate an instance
                            of <literal>ProcessingException</literal>.
                        </para>
                    </step>
                </stepalternatives>
            </step>
        </procedure>
    </section>

    <section>
        <title>Jersey &lit.jersey.message.MessageBodyWorkers; API</title>
        <para>
            In case you need to directly work with JAX-RS entity providers, for example to serialize an entity in your resource
            method, filter or in a composite entity provider, you would need to perform quite a lot of steps.
            You would need to choose the appropriate &lit.jaxrs.ext.MessageBodyWriter; based on the type, media type and
            other parameters. Then you would need to instantiate it, check it by <literal>isWriteable</literal> method and
            basically perform all the steps that are normally performed by Jersey
            (see <xref linkend="mbw.reader.selection.algorithm" />).
        </para>
        <para>
            To remove this burden from developers, Jersey exposes a proprietary public API that simplifies the manipulation
            of entity providers. The API is defined by &jersey.message.MessageBodyWorkers; interface and Jersey provides an
            implementation that can be injected using the &jaxrs.core.Context; injection annotation. The interface declares
            methods for selection of most appropriate &lit.jaxrs.ext.MessageBodyReader; and &lit.jaxrs.ext.MessageBodyWriter;
            based on the rules defined in JAX-RS spec, methods for writing and reading entity that ensure proper and timely
            invocation of interceptors and other useful methods.
        </para>
        <para>
            See the following example of usage of &lit.jersey.message.MessageBodyWorkers;.

            <example>
                <title>Usage of MessageBodyWorkers interface</title>
                <programlisting language="java" linenumbering="numbered"><![CDATA[@Path("workers")
public static class WorkersResource {

    @Context
    private MessageBodyWorkers workers;

    @GET
    @Produces("application/xml")
    public String getMyBeanAsString() {

        final MyBean myBean = new MyBean("Hello World!", 42);

        // buffer into which myBean will be serialized
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        // get most appropriate MBW
        final MessageBodyWriter<MyBean> messageBodyWriter =
                workers.getMessageBodyWriter(MyBean.class, MyBean.class,
                        new Annotation[]{}, MediaType.APPLICATION_XML_TYPE);

        try {
            // use the MBW to serialize myBean into baos
            messageBodyWriter.writeTo(myBean,
                MyBean.class, MyBean.class, new Annotation[] {},
                MediaType.APPLICATION_XML_TYPE, new MultivaluedHashMap<String, Object>(),
                baos);
        } catch (IOException e) {
            throw new RuntimeException(
                "Error while serializing MyBean.", e);
        }

        final String stringXmlOutput = baos.toString();
        // stringXmlOutput now contains XML representation:
        // "<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        // <myBean><anyString>Hello World!</anyString>
        // <anyNumber>42</anyNumber></myBean>"

        return stringXmlOutput;
    }
}]]></programlisting>
            </example>
        </para>
        <para>
            In the example a resource injects &lit.jersey.message.MessageBodyWorkers; and uses it for selection
            of the most appropriate &lit.jaxrs.ext.MessageBodyWriter;. Then the writer is utilized to serialize the entity
            into the buffer as XML document. The <literal>String</literal> content of the buffer is then returned.
            This will cause that Jersey will not use <literal>MyBeanMessageBodyWriter</literal>
            to serialize the entity as it is already in the <literal>String</literal> type
            (<literal>MyBeanMessageBodyWriter</literal> does not support <literal>String</literal>). Instead, a simple
            <literal>String</literal>-based  &lit.jaxrs.ext.MessageBodyWriter; will be chosen and it will only serialize the
            <literal>String</literal> with XML to the output entity stream by writing out the bytes of the
            <literal>String</literal>.
        </para>
        <para>
            Of course, the code in the example does not bring any benefit as the entity could
            have been serialized by <literal>MyBeanMessageBodyWriter</literal> by Jersey as in previous examples;
            the purpose of the example was to show how to use &lit.jersey.message.MessageBodyWorkers; in a resource method.
        </para>
    </section>

    <section>
        <title>Default Jersey Entity Providers</title>

        <para>
            Jersey internally contains entity providers for these types with combination of media types (in brackets):
        </para>
        <simplelist>
            <member>
                <literal>byte[]</literal> (<literal>*/*</literal>)
            </member>
            <member>
                &jdk6.String; (<literal>*/*</literal>)
            </member>
            <member>
                &jdk6.InputStream; (<literal>*/*</literal>)
            </member>
            <member>
                &jdk6.Reader; (<literal>*/*</literal>)
            </member>
            <member>
                &jdk6.File; (<literal>*/*</literal>)
            </member>
            <member>
                &jdk6.DataSource; (<literal>*/*</literal>)
            </member>
            <member>
                &jdk6.Source; (<literal>text/xml</literal>, <literal>application/xml</literal> and media types of the form
                <literal>application/*+xml</literal>)
            </member>
            <member>
                &jdk6.JAXBElement; (<literal>text/xml</literal>, <literal>application/xml</literal> and media types of the form
                <literal>application/*+xml</literal>)
            </member>
            <member>
                &jaxrs.core.MultivaluedMap; (<literal>application/x-www-form-urlencoded</literal>)
            </member>
            <member>
                &jaxrs.core.Form; (<literal>application/x-www-form-urlencoded</literal>)
            </member>
            <member>
                &jaxrs.core.StreamingOutput; ((<literal>*/*</literal>)) - this class can be used as an lightweight
                &lit.jaxrs.ext.MessageBodyWriter; that can be returned from a resource method
            </member>
            <member>
                &jdk6.Boolean;, &jdk6.Character; and &jdk6.Number; (<literal>text/plain</literal>) - corresponding
                primitive types supported via boxing/unboxing conversion
            </member>
        </simplelist>
        <para>
            For other media type supported in jersey please see the <xref linkend="media" /> which describes
            additional Jersey entity provider extensions for serialization to JSON, XML, serialization of collections,
            &jersey.media.multipart; and others.
        </para>
    </section>
</chapter>
