Definición de tipos de medio para recursos en aplicaciones RESTful
Los recursos se representan en diversos formatos. Los formatos XML, JavaScript Object Notation (JSON), Atom y binario como, por ejemplo, PNG, JPEG, GIF, texto plano y formatos de propiedad se utilizan para representar recursos. REST (Representational State Transfer) proporciona la flexibilidad para representar un solo recurso en varios formatos.
Antes de empezar
Defina los recursos en la aplicación web JAX-RS.
Acerca de esta tarea
Los recursos tienen representaciones. La representación de un recurso es el contenido del mensaje HTTP que se envía, o que devuelve el recurso mediante el URI. Cada representación admitida por un recurso tiene un tipo de medio correspondiente. Por ejemplo, si un recurso va a devolver contenido formateado en XML, puede usar application/xml como tipo de medio asociado en el mensaje HTTP.
En función de los requisitos de la aplicación, los recursos pueden devolver representaciones en un formato único preferido o en varios formatos. Por ejemplo, los recursos a los que se accede utilizando clientes de JavaScript podrían preferir representaciones JSON porque JSON es fácil de consumir.
JAX-RS proporciona anotaciones @Consumes y @Produces para declarar los tipos de medio que un método de recurso acepta para leer y escribir.
JAX-RS también correlaciona los tipos Java™ con representaciones de recursos utilizando los proveedores de entidades. Un proveedor de entidad MessageBodyReader lee una entidad de solicitud y deserializa la entidad de solicitud en un tipo Java. Un proveedor de entidad MessageBodyWriter serializa de un tipo Java en una entidad de respuesta.
Tipo Java | MessageBodyReader | MessageBodyWriter | Tipos de contenido admitidos |
---|---|---|---|
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 |
Tipos JAXB | X | X | text/xml, application/xml, application/*+xml |
javax.ws.rs.core.StreamingOutput | X | */* |
Si se utiliza un valor String como parámetro de entidad de solicitud, el proveedor de entidades MessageBodyReader deserializa el cuerpo de la solicitud en un nuevo valor String. Si se utiliza un tipo de JAXB como tipo de devolución en un método de recurso, el MessageBodyWriter serializa el objeto JAXB (Java Architecture for XML Binding) en un cuerpo de respuesta.
Si necesita una correlación personalizada de un tipo Java con una representación específica, consulte la información para utilizar un proveedor de entidades definido por la aplicación.
Si el cliente puede tratar varios formatos y desea que sea el servidor quien determine la mejor representación de recursos, lea la información acerca de cómo utilizar la negociación del contenido en aplicaciones de JAX-RS para prestar servicio a varios tipos de contenido.
Las especificaciones para XML, JSON y Atom proporcionan información detallada acerca de los formatos de las representaciones de recursos para las aplicaciones. Consulte las especificaciones para obtener más información sobre los formatos de representaciones de recursos.
Procedimiento
- Determine el formato de la representación de recursos como, por ejemplo, XML, JSON, o ATOM para utilizarlo en la solicitud o en la respuesta.
- Añada las anotaciones @Consumes y @Produces como corresponda en el método de recursos.
- Si el recurso necesita leer el contenido de la solicitud, añada un parámetro de entidad de solicitud en el método del recurso. El parámetro de entidad de solicitud es un parámetro Java único en el método que no tiene anotación.
- Si el método de recurso devuelve contenido en la respuesta, devuelve un objeto Java que un proveedor de entidades JAX-RS puede grabar. Este objeto Java se correlaciona con la entidad de respuestas en la respuesta HTTP. El objeto devuelto debe ser un tipo Java soportado por JAX-RS o recortado en un tipo javax.ws.rs.core.Response o javax.ws.rs.core.GenericEntity.
Resultados
Puede haber correlacionado entidades de solicitud con el parámetro de entidades de método de recursos y cualquier objeto de respuesta que se devuelva se correlacionará con la entidad de respuesta para la representación de recursos.
Ejemplo
En el ejemplo siguiente se muestra la definición de XML como representación de recursos para una aplicación de almacén de libros RESTful.
- Identifique los métodos de recursos de los que desea leer la entidad de solicitud o a los que desea devolver una entidad de respuesta.
En el ejemplo del método retrieveSpecificBookInformation que figura a continuación, no se lee ninguna entidad de solicitud. Sin embargo, sí se devuelve un objeto de respuesta. Este objeto recubre un objeto JAXB que contiene la información de entidad. La adición de la anotación @Produces en el método de recurso con un tipo de medio application/xml indica que el método de recurso siempre devuelve una representación XML con un tipo de medio application/xml.
Los clientes que tengan un valor de cabecera de solicitud HTTP de aceptación (Accept) que sea compatible con el tipo de medio application/xml invocan al método correctamente.
Los clientes que no tengan un valor de cabecera HTTP de aceptación compatible con el tipo de medio application/xml recibirán automáticamente un estado de respuesta 406 No aceptable que indica que el servidor no puede producir una respuesta aceptable.
En el ejemplo siguiente se identifican los métodos de recursos que leen la entidad de solicitud o devuelven una entidad de respuesta:
/* * 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) { /* … */ } }
- Identifique los métodos de recursos que necesite para consumir la información de solicitud.
En el siguiente fragmento, el método PUT del recurso de libros acepta el contenido de entidad de solicitud si se envía un tipo de medio text/plain, tal como se define en la anotación @Consumes. Este método devuelve el contenido con una representación text/plain tal como se especifica en las @Produces.
Si un cliente no envía un mensaje con un valor de tipo de contenido text/plain, no se invocará al método de recurso PUT. Si se envía Content-Type: application/xml en las cabeceras de la solicitud HTTP, no se invocará al método Java updateBookInformation.
El método DELETE ni lee información de una entidad de solicitud ni devuelve ninguna entidad de respuesta; por lo tanto, no precisa de ninguna anotación @Consumes ni @Produces.
En el ejemplo siguiente se identifican los métodos de recursos que consumen la información de solicitud:
/* * 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) { /* … */ } }
Qué hacer a continuación
Consulte en la especificación de JAX-RS una lista de todos los formatos de medios estándar admitidos por las representaciones.
Los usuarios avanzados pueden pensar en definir correlaciones personalizadas de tipos Java para las representaciones o utilizar la negociación de contenido para clientes con el fin de negociar o representaciones de recursos preferidas. Para obtener más información acerca de estas opciones, consulte la información sobre el uso de formatos de entidades definidas personalizadas o la información sobre cómo prestar servicio a varios tipos de contenido con negociación de contenido.