Implementación de la negociación de contenido en base a cabeceras HTTP

Las aplicaciones REST (Representational State Transfer) pueden devolver diferentes representaciones de recursos. Puede utilizar el contenido de la negociación basado en cabeceras de aceptación HTTP para determinar el contenido formato que se utiliza para intercambiar datos entre servidores y clientes.

Acerca de esta tarea

Los recursos pueden representar datos en formatos distintos. Puede implementar la negociación de contenido basada en URL, parámetros de solicitudes o cabeceras HTTP. En esta tarea se describe la negociación de contenido en base a las cabeceras de aceptación HTTP para enviar y recibir diferentes formatos de datos.

Cuando un navegador web realiza una solicitud, envía información sobre lo que está buscando al servidor en cabeceras. Una de estas cabeceras es la cabecera Accept (aceptación). La cabecera Accept indica al servidor qué formatos o tipos MIME está buscando el cliente. Puede utilizar las cabeceras Accept HTTP para determinar el formato de contenido que se utiliza para intercambiar datos.

Mientras la cabecera Accept no está visible como URL o parámetros, esta cabecera será el método más flexible de gestionar la negociación de contenido. También puede utilizar las cabeceras HTTP Accept, Accept-Charset, Accept-Language y Accept-Encoding para determinar el tipo de contenido que se devuelve del servidor.

Mediante la utilización de las cabeceras Accept HTTP puede asignar grados de calidad a respuestas aceptables. Por ejemplo, un cliente puede indicar que XML es el tipo de contenido de respuesta preferido. Sin embargo, si XML no está disponible, el cliente puede aceptar JSON o el texto plano para el formato.

Por ejemplo, si la cabecera Accept contiene un valor como, por ejemplo, application/json; q=1.0, text/xml;q=0.5, application/xml;q=0.5, este valor indica que JSON es el formato preferido pero que XML también se acepta.

En otros métodos de la negociación de contenido, normalmente hay un tipo de respuesta preferida. Sin embargo, puede utilizar las cabeceras Accept HTTP para informar al servicio de todos los tipos posibles que el cliente acepta en una solicitud. Además, la cabecera Accept HTTP y sus cabeceras relacionadas forman parte de la normativa HTTP.

Es importante tener en cuenta los aspectos siguientes cuando se implementa la negociación de contenido utilizando cabeceras HTTP. Es posible que algunos clientes envíen valores incorrectos y puede que algunos servicios no respeten las cabeceras Accept HTTP. Además, el proceso de todas las cabeceras HTTP y el cálculo de la respuesta óptima no es tan sencillo como solicitar contenido basándose en un URL o un parámetro de solicitud.

Procedimiento

  1. Añada un parámetro @javax.ws.rs.core.Context javax.ws.rs.core.Request al método de recurso.
  2. Utilice el objeto javax.ws.rs.core.Variant.VariantListBuilder para crear una lista de posibles variantes de respuesta admitidas por el sistema.
  3. Pruebe una respuesta aceptable.

    Utilice el método javax.ws.rs.core.Request.selectVariant(java.util.List<Variant>variant) para determinar si recibe una respuesta aceptable con el fin de enviarla al cliente. Una lista de posibles variantes de respuesta pasa al método. Una variante representa un tipo de combinación de medio, idioma y codificación. Consulte la documentación API javax.ws.rs.core.Variant y javax.ws.rs.core.Variant.VariantListBuilder para obtener más información acerca de crear una lista de variantes.

    En función de las posibles variantes de respuestas y las cabeceras HTTP de solicitud entrante, el método selectVariant(java.util.List<Variant> variant) devuelve la mejor variante de respuesta posible que coincida con las cabeceras HTTP.

    En el ejemplo siguiente se muestra la anotación @javax.ws.rs.core.Context para inyectar el tipo javax.ws.rs.core.Request. El tipo javax.ws.rs.core.Request ayuda a determinar la variante de respuesta óptima. En este ejemplo, se traspasa un objeto Request (solicitud) mediante el entorno de ejecución cuando se invoca al método de recurso.
    @Path("/resources")
    public class Resource
    {
        @Path("{resourceID}")
        @GET
        public Response getResource(@PathParam("resourceID") String resourceID, @Context Request req)
        {
            /* This method builds a list of possible variants. */
            /* You must call Variant.VariantListBuilder.add() object before calling the Variant.VariantListBuilder.build() object. */
            List<Variant> responseVariants =
                     Variant
                         .mediaTypes(
                                     MediaType.valueOf(MediaType.APPLICATION_XML + ";charset=UTF-8"),
                                     MediaType.valueOf(MediaType.APPLICATION_XML + ";charset=shift_jis"),
                                     MediaType
                                         .valueOf(MediaType.APPLICATION_JSON))
                         .encodings("gzip", "identity", "deflate").languages(Locale.ENGLISH,
                                                                             Locale.FRENCH,
                                                                             Locale.US).add().build();
    
              /* Based on the Accept* headers, an acceptable response variant is chosen.  If there is no acceptable variant,
              selectVariant will return a null value. */
    
             Variant bestResponseVariant = req.selectVariant(responseVariants);
             if(bestResponseVariant == null) {
    
                 /* Based on results, the optimal response variant can not be determined from the list given.  */ 
    
                return Response.notAcceptable().build();
             }
             MediaType responseMediaType = bestResponseVariant.getMediaType();
    
             /* This instruction obtains the acceptable language and modifies the response entity. */
    
             Locale responseLocale = bestResponseVariant.getLanguage();
             if(responseMediaType.isCompatible(MediaType.APPLICATION_XML_TYPE)) {
                 return Response.ok(/* entity in XML format */).type(MediaType.APPLICATION_XML).build();
             } else if (responseMediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
                 		return Response.ok(/* The entity is  in JSON format */)
    
    								.type(MediaType.APPLICATION_JSON).build();
             }
             return Response.notAcceptable(Variant.mediaTypes(MediaType.APPLICATION_XML_TYPE,
    				 				 MediaType.APPLICATION_JSON_TYPE).add().build()).build();
         }
     }

Resultados

Ha implementado la negociación de contenido utilizando cabeceras Accept para determinar los formatos para recursos que representan los datos.


Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxrs_contentnegotiation_httphead
File name: twbs_jaxrs_contentnegotiation_httphead.html