Apache Wink : JAX-RS Request and Response Entities
This page last changed on Oct 14, 2009 by michael.
Request and Response EntitiesRequest and response entities represent the main part of an HTTP request. Entities are also refered to as the "message body" or "payload". Entities are sent via a request, usually an HTTP POST and PUT method are used or they are returned in a response, this is relevant for all HTTP methods. Unlike other distributed systems technologies, there is generally no wrapper around an entity. For example, if a request is made for a binary PNG image represented here, http://example.com/user/abcd/portrait.png , the response entity is only the PNG image binary data. Resource methods have a single entity parameter that represents the main entity body. It is the only unannotated parameter allowed in a resource method. When using JAX-RS, request and response entites are mapped to and from Java types by Entity Providers that implement the JAX-RS interfaces, MessageBodyReader and MessageBodyWriter. Applications may provide their own MessageBodyReaders and MessageBodyWriters that take precedent over the runtime provided ones. Media Types (MIME) and javax.ws.rs.core.MediaTypeThe request and response entity can be any form of data, a way of identifying what the entities bits and bytes represent is needed. In requests and responses, the Content-Type HTTP header is used to indicate the type of entity currently being sent. The Content-Type value comes from a well known media type as registered in IANA. Common content types include "text/plain", "text/xml", "text/html", and "application/json". Correct Content-Type values are essential for clients and servers. "Unusual" behavior by clients such as browsers can be attributed to wrong content types. Media Types are also used in a request Accept header to indicate what type of resource representation the client wants to receive. Clients could indicate a preference as well, such as JSON before XML.
javax.ws.rs.core.MediaType has functionality and representations related to Media Types. @Consumes and @Produces AnnotationsAnnotating a class or a resource method with @Consumes and @Produces will help the JAX-RS runtime identify the appropriate methods to invoke for requests. For example: @Path("/example") public RootResource { @POST @Consumes("text/xml") @Produces("text/xml") public Response getOnlyXML(String incomingXML) { return Response.ok("only xml").type("text/xml").build(); } @GET @Produces("text/html", "text/plain") public String getText() { return "text representation"; } } In the previous code example, if a HTTP POST to "/example" was issued with a Content-Type header of "text/xml" and an Accept header of "text/xml", then the RootResource#getOnlyXML method would be invoked. If the same POST request was issued with an Accept header of "text/plain", then a 406 Not Acceptable response would be generated by the JAX-RS runtime and the method would not be invoked. It is a good practice to return a javax.ws.rs.core.Response with a .type() or .variant() call since it would guarantee a return content type. Notice that the above getText() code supports multiple data types. A javax.ws.rs.core.Response object returned must have a single concrete Content-Type value. In orer to select the best acceptable representation in the resource method, use either the @Context HttpHeaders#getAcceptableMediaTypes() or a @Context Request#selectVariant() method.
While resource methods may consume one media type for example XML and produce another such as JSON, most user requests expect the same media type that was sent in the request to be returned in the response. If the Content-Type header is empty and there is an entity, then the JAX-RS runtime will make the Content-Type be "application/octet-stream". If an Accept header is empty, then according to the HTTP specification, the Accept header is equivalent to */* which is a wildcard that matches anything.
JAX-RS Standard Entity Parameter TypesJAX-RS requires certain parameters to be supported for virtually any content type. The following table lists the supported content types:
Developers can use the previous Java types as entity parameters for requests and responses. @Path("/example") public class RootResource { @GET @Produces("text/xml") public Response getInfo() { byte[] entity = /* get the entity into a byte array */ return Response.ok(entity).type("text/xml").build(); } @POST @Consumes("application/json") @Produces("application/json") public StreamingOutput createItem(InputStream requestBodyStream) { /* read the requestBodyStream like a normal input stream */ return new StreamingOutput() { public void write(OutputStream output) throws IOException, WebApplicationException { byte[] out = /* get some bytes to write */ output.write(out); } }) } } Transfer EncodingTransfer or "chunked" encoding is handled by the container for incoming requests. The container or the application must do any transfer encoding for outgoing responses. Content EncodingContent for example "gzip" and or "deflate" encoding is handled by the application. However, some containers handle content encoding for developers and will uncompress content automatically or will with various configuration set. Check the container documentation. |
Document generated by Confluence on Nov 11, 2009 06:57 |