The behavior of a resource is determined by the HTTP methods (typically, GET, POST, PUT, DELETE) to which the resource is responding.
A request method designatorannotations are runtime annotations, defined by JAX-RS, and which correspond to the similarly named HTTP methods. Within a resource class file, HTTP methods are mapped to Java programming language methods using the request method designator annotations. The behavior of a resource is determined by which of the HTTP methods the resource is responding to. Jersey defines a set of request method designators for the common HTTP methods: @GET, @POST, @PUT, @DELETE, @HEAD, but you can create your own custom request method designators. Creating custom request method designators is outside the scope of this document.
The following example is an extract from the storage service sample that shows the use of the PUTmethod to create or update a storage container.
@PUT public Response putContainer() { System.out.println("PUT CONTAINER " + container); URI uri = uriInfo.getAbsolutePath(); Container c = new Container(container, uri.toString()); Response r; if (!MemoryStore.MS.hasContainer(c)) { r = Response.created(uri).build(); } else { r = Response.noContent().build(); } MemoryStore.MS.createContainer(c); return r; }
By default the JAX-RS runtime will automatically support the methods HEAD and OPTIONS if not explicitly implemented. For HEAD, the runtime will invoke the implemented GET method (if present) and ignore the response entity (if set). For OPTIONS, the Allow response header will be set to the set of HTTP methods support by the resource. In addition Jersey will return a WADL document describing the resource.
Methods decorated with request method designators must return void, a Java programming language type, or a javax.ws.rs.core.Response object. Multiple parameters may be extracted from the URI using the PathParam or QueryParam annotations as described in Extracting Request Parameters. Conversion between Java types and an entity body is the responsibility of an entity provider, such as MessageBodyReader or MessageBodyWriter. Methods that need to provide additional metadata with a response should return an instance of Response. The ResponseBuilder class provides a convenient way to create a Response instance using a builder pattern. The HTTP PUT and POST methods expect an HTTP request body, so you should use a MessageBodyReader for methods that respond to PUT and POST requests.
As PUT and POST can post be used to create or update, here is a bit more information on when you'd use each:
PUT has defined/specified semantics. POST can mean anything, so when using POSTit is up to the application to define the semantics.
When using PUT for creation, the client declares the URI for the newly created resource.
PUT has very clear semantics for creating and updating. The representation the client sends must be the same representation that is received using a GET, given the same media type. It does not specify partial update, a mistake people often make. A common application pattern is to use POST to create a resource and return a 201 response with a location header whose value is the URI to the newly-created resource. Thus in this pattern, the web service declares the URI for the newly-created resource.
Entity providers supply mapping services between representations and their associated Java types. There are two types of entity providers: MessageBodyReader and MessageBodyWriter. For HTTP requests, the MessageBodyReader is used to map an HTTP request entity body to method parameters. On the response side, a return value is mapped to an HTTP response entity body using a MessageBodyWriter. If the application needs to supply additional metadata, such as HTTP headers or a different status code, a method can return a Response that wraps the entity, and which can be built using Response.ResponseBuilder.
The following list contains the standard types that are supported automatically for entities. You only need to write an entity provider if you are not choosing one of the following, standard types.
byte[] — All media types (*/*)
java.lang.String — All text media types (text/*)
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 application/*+xml)
javax.xml.bind.JAXBElement and application-supplied JAXB classes XML media types (text/xml, application/xml, and application/*+xml)
MultivaluedMap<String, String> — Form content (application/x-www-form-urlencoded)
StreamingOutput — All media types (*/*), MessageBodyWriter only
The following example shows how to use MessageBodyReader with the @Consumes and @Provider annotations:
@Consumes("application/x-www-form-urlencoded") @Provider public class FormReader implements MessageBodyReader<NameValuePair> {
The following example shows how to use MessageBodyWriter with the @Produces and @Provider annotations:
@Produces("text/html") @Provider public class FormWriter implements MessageBodyWriter<Hashtable<String, String>> {
The following example shows how to use ResponseBuilder:
@GET public Response getItem() { System.out.println("GET ITEM " + container + " " + item); Item i = MemoryStore.MS.getItem(container, item); if (i == null) throw new NotFoundException("Item not found"); Date lastModified = i.getLastModified().getTime(); EntityTag et = new EntityTag(i.getDigest()); ResponseBuilder rb = request.evaluatePreconditions(lastModified, et); if (rb != null) return rb.build(); byte[] b = MemoryStore.MS.getItemData(container, item); return Response.ok(b, i.getMimeType()). lastModified(lastModified).tag(et).build(); }