46.4. Parsing Requests and Responses

Overview

An essential aspect of making HTTP invocations is that the client must be able to parse the outgoing request messages and the incoming responses. In JAX-RS 2.0, the key concept is the Entity class, which represents a raw message tagged with a media type. In order to parse the raw message, you can register multiple entity providers, which have the capability to convert media types to and from particular Java types.
In other words, in the context of JAX-RS 2.0, an Entity is the representation of a raw message and an entity provider is the plug-in that provides the capability to parse the raw message (based on the media type).

Entities

An Entity is a message body augmented by metadata (media type, language, and encoding). An Entity instance holds the message in a raw format and is associated with a specific media type. To convert the contents of an Entity object to a Java object you require an entity provider, which is capable of mapping the given media type to the required Java type.

Variants

A javax.ws.rs.core.Variant object encapsulates the metadata associated with an Entity, as follows:
  • Media type,
  • Language,
  • Encoding.
Effectively, you can think of an Entity as consisting of the HTTP message contents, augmented by Variant metadata.

Entity providers

An entity provider is a class that provides the capability of mapping between a media type and a Java type. Effectively, you can think of an entity provider as a class that provides the ability to parse messages of a particular media type (or possibly of multiple media types). There are two different varieties of entity provider:
MessageBodyReader
Provides the capability of mapping from media type(s) to a Java type.
MessageBodyWriter
Provides the capability of mapping from a Java type to a media type.

Standard entity providers

Entity providers for the following Java and media type combinations are provided as standard:
byte[]
All media types ( */* ).
java.lang.String
All media types ( */* ).
java.io.InputStream
All media types ( */* ).
java.io.Reader
All media types ( */* ).
java.io.File
All media types ( */* ).
javax.activation.DataSource
All media types ( */* ).
javax.xml.transform.Source
XML types (text/xml, application/xml, and media types of the form application/*+xml).
javax.xml.bind.JAXBElement and application-supplied JAXB classes
XML types (text/xml, application/xml, and media types of the form application/*+xml).
MultivaluedMap<String,String>
Form content (application/x-www-form-urlencoded).
StreamingOutput
All media types (*/*), MessageBodyWriter only.
java.lang.Boolean, java.lang.Character, java.lang.Number
Only for text/plain. Corresponding primitive types supported through boxing/unboxing conversion.

Response object

The default return type is the javax.ws.rs.core.Response type, which represents an untyped response. The Response object provides access to the complete HTTP response, including the message body, HTTP status, HTTP headers, media type, and so on.

Accessing the response status

You can access the response status, either through the getStatus method (which returns the HTTP status code):
int status = resp.getStatus();
Or though the getStatusInfo method, which also provides a description string:
String statusReason = resp.getStatusInfo().getReasonPhrase();

Accessing the returned headers

You can access the HTTP headers using any of the following methods:
MultivaluedMap<String,Object>
getHeaders()

MultivaluedMap<String,String>
getStringHeaders()

String
getHeaderString(String name)
For example, if you know that the Response has a Date header, you could access it as follows:
String dateAsString = resp.getHeaderString("Date");

Accessing the returned cookies

You can access any new cookies set on the Response using the getCookies method, as follows:
import javax.ws.rs.core.NewCookie;
...
java.util.Map<String,NewCookie> cookieMap = resp.getCookies();
java.util.Collection<NewCookie> cookieCollection = cookieMap.values();

Accessing the returned message content

You can access the returned message content by invoking one of the readEntity methods on the Response object. The readEntity method automatically invokes the available entity providers to convert the message to the requested type (specified as the first argument of readEntity). For example, to access the message content as a String type:
String messageBody = resp.readEntity(String.class);

Collection return value

If you need to access the returned message as a Java generic type—for example, as a List or Collection type—you can specify the request message type using the javax.ws.rs.core.GenericType<T> construction. For example:
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.GenericType;
import java.util.List;
...
GenericType<List<String>> stringListType = new GenericType<List<String>>() {};

Client client = ClientBuilder.newClient();
List<String> bookNames = client.target("http://example.org/bookstore/booknames")
                     .request("text/plain")
                     .get(stringListType);