Implémentation de la négociation de contenu basée sur des en-têtes HTTP

Les applications REST (Representational State Transfer) peuvent retourner différentes représentations des ressources. Vous pouvez utiliser la négociation de contenu basée sur des en-têtes HTTP pour déterminer le format de contenu utilisé pour échanger des données entre les serveurs et les clients.

Pourquoi et quand exécuter cette tâche

Les ressources peuvent représenter les données dans différents formats. Vous pouvez implémenter la négociation de contenu basée sur des URL, des paramètres de demande ou des en-têtes HTTP. Cette tâche explique la négociation de contenu basée sur des en-têtes HTTP pour envoyer et recevoir différents formats de contenu.

Lorsqu'un navigateur fait une demande, il envoie au serveur les informations sur ce qu'il recherche dans des en-têtes. L'un de ces en-têtes est l'en-tête Accept. Cet en-tête indique au serveur les formats ou les types MIME que le client recherche. Vous pouvez utiliser des en-têtes HTTP Accept pour déterminer le format de contenu utilisé pour échanger des données.

Bien que cet en-tête ne soit pas aussi visible que des URL ou des paramètres, il offre une méthode plus souple pour gérer la négociation de contenu. Vous pouvez également utiliser les en-têtes HTTP Accept, Accept-Charset, Accept-Language et Accept-Encoding pour déterminer le type de contenu retourné par le serveur.

En utilisant des en-têtes HTTP Accept, vous pouvez affecter un degré de qualité aux réponses acceptables. Par exemple, un client peut indiquer que XML est le type de contenu de réponse préféré. Toutefois, si XML n'est pas disponible, le client peut accepter JSON ou du texte ordinaire comme format.

Par exemple, si l'en-tête Accept contient une valeur telle que application/json; q=1.0, text/xml;q=0.5, application/xml;q=0.5, cette valeur indique que JSON est le format préféré, mais que XML est également acceptable.

Dans d'autres méthodes de négociation du contenu, un seul type de réponse préféré existe généralement. Toutefois, vous pouvez utiliser des en-têtes HTTP Accept pour signaler au service tous les types possibles acceptables par le client dans une réponse. En outre, l'en-tête HTTP Accept et ses en-têtes associés font partie de la norme HTTP.

Il est important de tenir compte des éléments suivants lors de l'implémentation de la négociation à l'aide d'en-têtes HTTP. Certains clients peuvent envoyer des valeurs incorrectes et certains services peuvent ne pas respecter les en-têtes HTTP Accept. D'autre part, le traitement de tous les en-têtes HTTP et le calcul de la réponse optimale ne sont pas aussi simples que de demander du contenu en fonction d'une URL ou d'un paramètres de demande.

Procédure

  1. Ajoutez un paramètre @javax.ws.rs.core.Context javax.ws.rs.core.Request à la méthode de ressource.
  2. Utilisez l'objet javax.ws.rs.core.Variant.VariantListBuilder pour créer une liste de variantes de réponse possibles prises en charge par le service.
  3. Testez une réponse acceptable.

    Utilisez la méthode javax.ws.rs.core.Request.selectVariant(java.util.List<Variant>variant) pour déterminer si vous recevez une réponse acceptable à envoyer au client. La liste des variantes de réponse possibles est envoyée à la méthode. Une variante représente une combinaison de type de support, de langue et de codage. Voir la documentation des API javax.ws.rs.core.Variant et javax.ws.rs.core.Variant.VariantListBuilder pour plus d'informations sur la création d'une liste de variantes.

    En fonction des variantes de réponse possibles et des en-têtes de HTTP de demande entrante, la méthode selectVariant(java.util.List<Variant> variant) retourne la meilleure variante de réponse possible qui correspond aux en-têtes HTTP.

    L'exemple suivant illustre l'utlisation de l'annotation @javax.ws.rs.core.Context pour injecter le type javax.ws.rs.core.Request. Le type javax.ws.rs.core.Request permet de déterminer la variante de la réponse optimale. Dans cet exemple, un objet Request est envoyé par l'environnement d'exécution lorsque la méthode de ressource est appelée.
    @Path("/resources")
    public class Resource
    {
        @Path("{resourceID}")
        @GET
        public Response getResource(@PathParam("resourceID") String resourceID, @Context Request req)
        {
            /* Cette méthode crée la liste des variantes possibles. */
            /* Vous devez appeler l'objet Variant.VariantListBuilder.add() avant l'objet Variant.VariantListBuilder.build(). */
            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();
    
              /* En fonction des en-têtes Accept*, une variante de réponse est choisie.  Si aucune variante n'est acceptable,
              selectVariant retourne une valeur null. */
    
             Variant bestResponseVariant = req.selectVariant(responseVariants);
             if(bestResponseVariant == null) {
    
                 /* Selon les résultats, la variante de réponse optimale ne peut pas être déterminée à partir de la liste fournie.  */ 
    
                return Response.notAcceptable().build();
             }
             MediaType responseMediaType = bestResponseVariant.getMediaType();
    
             /* Cette instruction obtient la langue acceptable et modifie l'entité de réponse. */
    
             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();
         }
     }

Résultats

Vous avez implémenté la négociation de contenu en utilisant des en-têtes Accept pour déterminer les formats des ressources qui représentent des données.


Icône indiquant le type de rubrique Rubrique de tâche



Icône d'horodatage Dernière mise à jour: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxrs_contentnegotiation_httphead
Nom du fichier : twbs_jaxrs_contentnegotiation_httphead.html