| <?xml version="1.0"?> | 
 | <!-- | 
 |  | 
 |     Copyright (c) 2010, 2021 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="representations"> | 
 |     <title>Representations and Responses</title> | 
 |  | 
 |     <section xml:id="reps-and-types"> | 
 |         <title>Representations and Java Types</title> | 
 |         <para>Previous sections on &jaxrs.Produces; and &jaxrs.Consumes; annotations | 
 |             referred to media type of an entity representation. Examples above depicted resource | 
 |             methods that could consume and/or produce String Java type for a number of | 
 | 	    different media types. This approach is easy to understand and relatively | 
 | 	    straightforward when applied to simple use cases. | 
 | 	    </para> | 
 |  | 
 | 	    <para>To cover also other cases, handling non-textual data for example or handling data stored in the file system, etc., | 
 |             JAX-RS implementations are required to support also other kinds of media type | 
 |             conversions where additional, non-String, Java types are being utilized. Following is a short listing of the Java types | 
 |             that are supported out of the box with respect to supported media type: | 
 |             <itemizedlist> | 
 |             	<listitem>All media types (<literal>*/*</literal>) | 
 |             		<itemizedlist> | 
 |             			<listitem><literal>byte[]</literal></listitem> | 
 | 				<listitem><literal>java.lang.String</literal></listitem> | 
 | 				<listitem><literal>java.io.Reader</literal> (inbound only)</listitem> | 
 | 				<listitem><literal>java.io.File</literal></listitem> | 
 | 				<listitem><literal>jakarta.activation.DataSource</literal></listitem> | 
 | 				<listitem><literal>jakarta.ws.rs.core.StreamingOutput</literal> (outbound only)</listitem> | 
 |             		</itemizedlist> | 
 | 		</listitem> | 
 |             	<listitem>XML media types (<literal>text/xml</literal>, <literal>application/xml</literal> and <literal>application/...+xml</literal>) | 
 |             		<itemizedlist> | 
 |             			<listitem><literal>javax.xml.transform.Source</literal></listitem> | 
 |             			<listitem><literal>jakarta.xml.bind.JAXBElement</literal></listitem> | 
 |             			<listitem>Application supplied JAXB classes (types annotated with | 
 | 	    <link xlink:href="http://docs.oracle.com/javase/6/docs/api/jakarta.xml.bind/annotation/XmlRootElement.html">@XmlRootElement</link> | 
 | 	    or<link xlink:href="http://docs.oracle.com/javase/6/docs/api/jakarta.xml.bind/annotation/XmlType.html">@XmlType</link>)</listitem> | 
 |              		</itemizedlist> | 
 |             	</listitem> | 
 |                 <listitem>Form content (<literal>application/x-www-form-urlencoded</literal>) | 
 |                         <itemizedlist> | 
 |                           <listitem><literal>MultivaluedMap<String,String></literal></listitem> | 
 |                         </itemizedlist> | 
 |                  </listitem> | 
 |                  <listitem>Plain text (<literal>text/plain</literal>) | 
 |                         <itemizedlist> | 
 |                           <listitem><literal>java.lang.Boolean</literal></listitem> | 
 |                           <listitem><literal>java.lang.Character</literal></listitem> | 
 |                           <listitem><literal>java.lang.Number</literal></listitem> | 
 |                         </itemizedlist> | 
 |                 </listitem> | 
 |             </itemizedlist> | 
 |         </para> | 
 |  | 
 |         <para>Unlike method parameters that are associated with the extraction of | 
 |             request parameters, the method parameter associated with the | 
 |             representation being consumed does not require annotating. In other words the | 
 |             representation (entity) parameter does not require a specific 'entity' annotation. A method parameter | 
 |             without an annotation is an entity. A maximum of | 
 |             one such unannotated method parameter may exist since there may only be a | 
 |             maximum of one such representation sent in a request. | 
 |         </para> | 
 |  | 
 |         <para>The representation being produced corresponds to what is returned by | 
 |             the resource method. For example JAX-RS makes it simple to produce images | 
 |             that are instance of | 
 |             <literal>File</literal> | 
 |             as follows: | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Using | 
 |                     <code>File</code> | 
 |                     with a specific media type to produce a response | 
 |                 </title> | 
 |                 <programlisting language="java" linenumbering="numbered">@GET | 
 | @Path("/images/{image}") | 
 | @Produces("image/*") | 
 | public Response getImage(@PathParam("image") String image) { | 
 |   File f = new File(image); | 
 |  | 
 |   if (!f.exists()) { | 
 |     throw new WebApplicationException(404); | 
 |   } | 
 |  | 
 |   String mt = new MimetypesFileTypeMap().getContentType(f); | 
 |   return Response.ok(f, mt).build(); | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>The | 
 |             <literal>File</literal> type can also be used when consuming a representation (request entity). | 
 |             In that case a temporary file will be created from the incoming request entity and passed as a | 
 |             parameter to the resource method. | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             The <literal>Content-Type</literal> response header | 
 |             (if not set programmatically as described in the next section) | 
 |             will be automatically set based on the media types declared by &jaxrs.Produces; annotation. | 
 |  Given the following method, the most acceptable media type is used when multiple output media types are allowed: | 
 |         </para> | 
 |         <para> | 
 |             <programlisting language="java" linenumbering="numbered">@GET | 
 | @Produces({"application/xml", "application/json"}) | 
 | public String doGetAsXmlOrJson() { | 
 |   ... | 
 | }</programlisting> | 
 |  | 
 |             If <literal>application/xml</literal> is the most acceptable media type defined | 
 |             by the request (e.g. by header <literal>Accept: application/xml</literal>), then the | 
 |             <literal>Content-Type</literal> response header | 
 |             will be set to <literal>application/xml</literal>. | 
 |         </para> | 
 |     </section> | 
 |  | 
 |     <section> | 
 |         <title>Building Responses</title> | 
 |  | 
 |         <para>Sometimes it is necessary to return additional | 
 |             information in response to a HTTP request. Such information may be built | 
 |             and returned using &jaxrs.core.Response; and &jaxrs.core.Response.ResponseBuilder;. | 
 |             For example, a common RESTful pattern for the creation of a new resource | 
 |             is to support a POST request that returns a 201 (Created) status code and | 
 |             a | 
 |             <literal>Location</literal> | 
 |             header whose value is the URI to the newly | 
 |             created resource. This may be achieved as follows: | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Returning 201 status code and adding | 
 |                     <literal>Location</literal> | 
 |                     header in response to POST request | 
 |                 </title> | 
 |                 <programlisting language="java" linenumbering="numbered">@POST | 
 | @Consumes("application/xml") | 
 | public Response post(String content) { | 
 |   URI createdUri = ... | 
 |   create(content); | 
 |   return Response.created(createdUri).build(); | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>In the above no representation produced is returned, this can be | 
 |             achieved by building an entity as part of the response as follows: | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Adding an entity body to a custom response</title> | 
 |                 <programlisting language="java" linenumbering="numbered">@POST | 
 | @Consumes("application/xml") | 
 | public Response post(String content) { | 
 |   URI createdUri = ... | 
 |   String createdContent = create(content); | 
 |   return Response.created(createdUri).entity(Entity.text(createdContent)).build(); | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>Response building provides other functionality such as setting the | 
 |             entity tag and last modified date of the representation. | 
 |         </para> | 
 |     </section> | 
 |  | 
 |     <section> | 
 |         <title>WebApplicationException and Mapping Exceptions to Responses</title> | 
 |  | 
 |         <para>Previous section shows how to return HTTP responses, | 
 |               that are built up programmatically. | 
 |             It is possible to use the very same mechanism | 
 |             to return HTTP errors directly, | 
 |             e.g. when handling exceptions in a try-catch block. | 
 |             However, to better align with the Java programming model, | 
 |             JAX-RS allows to define direct mapping of Java exceptions to HTTP error responses. | 
 |         </para> | 
 |  | 
 |         <para>The following example shows throwing | 
 |             <literal>CustomNotFoundException</literal> | 
 |             from a resource method in order to return an error HTTP response to the client: | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Throwing exceptions to control response</title> | 
 |                 <programlisting language="java" linenumbering="numbered">@Path("items/{itemid}/") | 
 | public Item getItem(@PathParam("itemid") String itemid) { | 
 |   Item i = getItems().get(itemid); | 
 |   if (i == null) { | 
 |     throw new CustomNotFoundException("Item, " + itemid + ", is not found"); | 
 |   } | 
 |  | 
 |   return i; | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>This exception is an application specific exception that extends &jaxrs.WebApplicationException; | 
 |             and builds a HTTP response with the 404 status code and an optional | 
 |             message as the body of the response: | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Application specific exception implementation</title> | 
 |                 <programlisting language="java" linenumbering="numbered">public class CustomNotFoundException extends WebApplicationException { | 
 |  | 
 |   /** | 
 |   * Create a HTTP 404 (Not Found) exception. | 
 |   */ | 
 |   public CustomNotFoundException() { | 
 |     super(Responses.notFound().build()); | 
 |   } | 
 |  | 
 |   /** | 
 |   * Create a HTTP 404 (Not Found) exception. | 
 |   * @param message the String that is the entity of the 404 response. | 
 |   */ | 
 |   public CustomNotFoundException(String message) { | 
 |     super(Response.status(Responses.NOT_FOUND). | 
 |     entity(message).type("text/plain").build()); | 
 |   } | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>In other cases it may not be appropriate to throw instances of &jaxrs.WebApplicationException;, | 
 |             or classes that extend &jaxrs.WebApplicationException;, and instead it may be preferable to map an existing exception to a | 
 |             response. For such cases it is possible to use a custom exception mapping provider. The provider must implement | 
 |             the &jaxrs.ext.ExceptionMapper; interface. For example, the following | 
 |             maps the | 
 |             <link xlink:href="http://docs.oracle.com/javaee/5/api/jakarta.persistence/EntityNotFoundException.html">EntityNotFoundException</link> | 
 |             to a HTTP 404 (Not Found) response: | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Mapping generic exceptions to responses</title> | 
 |                 <programlisting language="java" linenumbering="numbered">@Provider | 
 | public class EntityNotFoundMapper implements ExceptionMapper<jakarta.persistence.EntityNotFoundException> { | 
 |   public Response toResponse(jakarta.persistence.EntityNotFoundException ex) { | 
 |     return Response.status(404). | 
 |       entity(ex.getMessage()). | 
 |       type("text/plain"). | 
 |       build(); | 
 |   } | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>The above class is annotated with &jaxrs.ext.Provider;, this declares that the class is of interest to the JAX-RS runtime. Such a | 
 |             class may be added to the set of classes of the &jaxrs.core.Application; instance that is configured. When an application throws an | 
 |             <link xlink:href="http://docs.oracle.com/javaee/6/api/jakarta.persistence/EntityNotFoundException.html">EntityNotFoundException</link> | 
 |             the | 
 |             <literal>toResponse</literal> | 
 |             method of the | 
 |             <literal>EntityNotFoundMapper</literal> | 
 |             instance will be invoked. | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             Jersey supports extension of the exception mappers. These extended mappers must implement | 
 |             the <literal>org.glassfish.jersey.spi.ExtendedExceptionMapper</literal> interface. This interface additionally | 
 |             defines method <literal>isMappable(Throwable)</literal> which will be invoked by the Jersey runtime | 
 |             when exception is thrown and this provider is considered as mappable based on the exception type. Using this | 
 |             method the provider can reject mapping of the exception before the method <literal>toResponse</literal> | 
 |             is invoked. The provider can for example check the exception parameters and based on them return false | 
 |             and let other provider to be chosen for the exception mapping. | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             Since Jersey 3.1.0 the default <literal>ExceptionMapper</literal> is implemented. | 
 |             It is required by JAX-RS 3.1 specification (&jaxrs31.exceptionMapperProvider;). | 
 |             The default behaviour of the mapper is to return a message from an exception caught and set the response status | 
 |             to 500 (internal server error). In case of a &jaxrs.WebApplicationException; with a response that response is returned. | 
 |             If response inside the &lit.jaxrs.WebApplicationException; is NULL the exception is being processed according to the | 
 |             default behaviour. | 
 |  | 
 |             The Default exception mapper is package private and can not be referenced. Its presence is required only by | 
 |             JAX-RS 3.1 specification. Processing of the default Exception Mapper occurs at the very end of the exception | 
 |             processing chain. It is invoked only if nothing else in the chain was invoked before. | 
 |         </para> | 
 |  | 
 |     </section> | 
 |  | 
 |     <section> | 
 |         <title>Conditional GETs and Returning 304 (Not Modified) Responses</title> | 
 |  | 
 |         <para>Conditional GETs are a great way to reduce bandwidth, and | 
 |             potentially improve on the server-side performance, depending on how the information used | 
 |             to determine conditions is calculated. A well-designed web site may for example return | 
 |             304 (Not Modified) responses for many of static images it serves. | 
 |         </para> | 
 |  | 
 |         <para>JAX-RS provides support for conditional GETs using the contextual interface &jaxrs.core.Request;. | 
 |         </para> | 
 |  | 
 |         <para>The following example shows conditional GET support:</para> | 
 |  | 
 |         <para> | 
 |             <example> | 
 |                 <title>Conditional GET support</title> | 
 |                 <programlisting language="java" linenumbering="numbered">public SparklinesResource( | 
 |   @QueryParam("d") IntegerList data, | 
 |   @DefaultValue("0,100") @QueryParam("limits") Interval limits, | 
 |   @Context Request request, | 
 |   @Context UriInfo ui) { | 
 |   if (data == null) { | 
 |     throw new WebApplicationException(400); | 
 |   } | 
 |  | 
 |   this.data = data; | 
 |   this.limits = limits; | 
 |  | 
 |   if (!limits.contains(data)) { | 
 |     throw new WebApplicationException(400); | 
 |   } | 
 |  | 
 |   this.tag = computeEntityTag(ui.getRequestUri()); | 
 |  | 
 |   if (request.getMethod().equals("GET")) { | 
 |     Response.ResponseBuilder rb = request.evaluatePreconditions(tag); | 
 |     if (rb != null) { | 
 |       throw new WebApplicationException(rb.build()); | 
 |     } | 
 |   } | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |  | 
 |         <para>The constructor of the | 
 |             <literal>SparklinesResource</literal> | 
 |             root | 
 |             resource class computes an entity tag from the request URI and then calls | 
 |             the | 
 |             <link xlink:href="&jaxrs.javadoc.uri;/core/Request.html#evaluatePreconditions(jakarta.ws.rs.core.EntityTag)">request.evaluatePreconditions</link> | 
 |             with that entity tag. If a client request contains an | 
 |             <literal>If-None-Match</literal> | 
 |             header with a value that contains the | 
 |             same entity tag that was calculated then the | 
 |             <link xlink:href="&jaxrs.javadoc.uri;/core/Request.html#evaluatePreconditions(jakarta.ws.rs.core.EntityTag)">evaluatePreconditions</link> | 
 |             returns a pre-filled out response, with the 304 status code and entity tag | 
 |             set, that may be built and returned. Otherwise, | 
 |             <link xlink:href="&jaxrs.javadoc.uri;/core/Request.html#evaluatePreconditions(jakarta.ws.rs.core.EntityTag)">evaluatePreconditions</link> | 
 |             returns | 
 |             <literal>null</literal> | 
 |             and the normal response can be | 
 |             returned. | 
 |         </para> | 
 |  | 
 |         <para>Notice that in this example the constructor of a resource class is used | 
 |             to perform actions that may otherwise have to be duplicated to | 
 |             be invoked for each resource method. The life cycle of resource classes is per-request | 
 |             which means that the resource instance is created for each request and therefore | 
 |             can work with request parameters and for example make changes to the request processing by | 
 |             throwing an exception as it is shown in this example. | 
 |         </para> | 
 |     </section> | 
 | </chapter> |