Defining media types for resources in RESTful applications
Resources are represented by multiple formats. XML, JavaScript Object Notation (JSON), Atom, binary formats such as PNG, JPEG, GIF, plain text, and proprietary formats are used to represent resources. Representational State Transfer (REST) provides the flexibility to represent a single resource in multiple formats.
Before you begin
Define the resources in the JAX-RS web application.
About this task
Resources have representations. A resource representation
is the content in the HTTP message that is sent to, or returned from
the resource using the URI. Each representation that a resource supports
has a corresponding media type. For example, if a resource is going
to return content formatted as XML, you can use application/xml
as
the associated media type in the HTTP message.
Depending on the requirements of your application, resources can return representations in a preferred single format or in multiple formats. For example, resources that are accessed using JavaScript clients might prefer JSON representations because JSON is easy to consume.
JAX-RS provides @Consumes and @Produces annotations to declare the media types that are acceptable for a resource method to read and write.
JAX-RS
also maps Java™ types to and
from resource representations using entity providers. A MessageBodyReader
entity
provider reads a request entity and deserializes the request entity
into a Java type. A MessageBodyWriter
entity
provider serializes from a Java type
into a response entity.
Java type | MessageBodyReader | MessageBodyWriter | Supported Content types |
---|---|---|---|
byte[] | X | X | */* |
java.io.InputStream | X | X | */* |
java.io.Reader | X | X | */* |
java.lang.String | X | X | */* |
java.io.File | X | X | */* |
javax.activation.DataSource | X | X | */* |
javax.xml.transform.Source | X | X | text/xml, application/xml, application/*+xml |
javax.ws.rs.core.MultivaluedMap | X | X | application/x-www-form-urlencoded |
JAXB types | X | X | text/xml, application/xml, application/*+xml |
javax.ws.rs.core.StreamingOutput | X | */* |
If a String
value is used as the
request entity parameter, the MessageBodyReader
entity
provider deserializes the request body into a new String
.
If a JAXB type is used as the return type on a resource method, the
MessageBodyWriter serializes the Java Architecture
for XML Binding (JAXB) object into a response body.
If you need a custom mapping from a Java type to a specific representation, see the information for using an application-defined entity provider.
If your client can handle multiple formats and you want the server to determine the best resource representation to return, read about using content negotiation in JAX-RS applications to serve multiple content types.
The specifications for XML, JSON, and Atom provide details regarding the formats of resource representations for applications. See the specifications to learn more about the formats of resource representations.
Procedure
- Determine the resource representation format such as XML, JSON, or ATOM to use for either the request or the response.
- Add the @Consumes and @Produces annotations appropriately to the resource method.
- If the resource needs to read the content of the request,
add a request entity parameter to the resource method. The request entity parameter is a single Java parameter on the method that does not have an annotation.
- If the resource method returns content in the response,
return a Java object that is
writable by a JAX-RS entity provider. This Java object is mapped to the response entity in the HTTP response. The returned object must be a JAX-RS supported Java type or wrapped in a javax.ws.rs.core.Response or javax.ws.rs.core.GenericEntity type.
Results
You have mapped the request entities to the resource method entity parameter and any response objects that are returned are mapped to the response entity for the resource representation.
Example
The following example illustrates defining XML as the resource representation for a RESTful bookstore application.
- Identify the resource methods that you want to read the request
entity or return a response entity.
In the retrieveSpecificBookInformation method example that follows, there is no request entity that is read. However, there is a response object that is returned. This object wraps a JAXB object that contains the entity information. Adding the @Produces annotation on the resource method with a media type of
application/xml
indicates that the resource method always returns an XML representation with a media type ofapplication/xml
.Clients that have an Accept HTTP request header value compatible with the
application/xml
media type invoke the method correctly.Clients that do not have an Accept HTTP header value compatible with the
application/xml
media type automatically receive a406 Not Acceptable
response status which indicates that the server cannot produce an acceptable response.The following example identifies the resource methods that read the request entity or return a response entity:
/* * Book.java * This class represents individual books. The @Produces annotation specifies a media type of application/xml. */ @Path(“/bookstore/books/{bookID}”) public class Book { @GET @Produces(“application/xml”) public javax.ws.rs.core.Response retrieveSpecificBookInformation(@PathParam(“bookID”) String theBookID, @Context javax.ws.rs.core.HttpHeaders headers) { /* … */ return Response.ok(/* JAXB object to represent response body entity */).expires(/* Expires response header value*/).header(“CustomHeaderName”, “CustomHeaderValue”).build(); } @PUT public String updateBookInformation(@PathParam(“bookID”) String theBookID, String theRequestEntity, @javax.ws.rs.HeaderParam(“Content-Length”) String contentLengthHeader) { /* … */ } @DELETE public void removeBook(@PathParam(“bookID”) String theBookID) { /* … */ } }
- Identify the resource methods that need to consume the request
information.
In the following snippet, the PUT method on the book resource accepts the request entity content if a media type of
text/plain
is sent, as defined in the @Consumes annotation. This method returns content with atext/plain
representation as specified in the @Produces annotations.If a client does not send a message with a Content-Type value of
text/plain
, then the PUT resource method is not invoked. IfContent-Type: application/xml
is sent in the HTTP request headers, theupdateBookInformation
Java method is not be called.The DELETE method neither reads a request entity nor returns a response entity; therefore, it does not require either an @Consumes or an @Produces annotation.
The following example identifies the resource methods that consume the request information:
/* * Book.java * This class represents represent individual books with custom headers. */ @Path(“/bookstore/books/{bookID}”) public class Book { @GET @Produces(“application/xml”) public javax.ws.rs.core.Response retrieveSpecificBookInformation(@PathParam(“bookID”) String theBookID, @Context javax.ws.rs.core.HttpHeaders headers) { /* … */ return Response.ok(/* JAXB object to represent response body entity */).expires(/* Expires response header value).header(“CustomHeaderName”, “CustomHeaderValue”).build(); } @PUT @Consumes(“text/plain”) @Produces(“text/plain”) public String updateBookInformation(@PathParam(“bookID”) String theBookID, String theRequestEntity, @javax.ws.rs.HeaderParam(“Content-Length”) String contentLengthHeader) { /* … */ String responseEntity = /* a plain text representation */; return responseEntity; } @DELETE public void removeBook(@PathParam(“bookID”) String theBookID) { /* … */ } }
What to do next
See the JAX-RS specification for a list of all the standard media formats that are supported for representations.
Advanced users might consider defining custom mappings of Java types to representations or using content negotiation for clients to negotiate preferred resource representations. To learn more about these options, see the using custom defined entity formats information or the serving multiple content types with content negotiation information.