Spring MVC Content Negotiation

Spring MVC Content Negotiation

1. Vue d'ensemble

Cet article explique comment implémenter la négociation de contenu dans un projet Spring MVC.

En règle générale, il existe trois options pour déterminer le type de support d'une demande:

  • Utilisation de suffixes d'URL (extensions) dans la requête (par exemple.xml/.json)

  • Utilisation du paramètre URL dans la requête (par exemple?format=json)

  • Utilisation de l'en-têteAccept dans la requête

Par défaut, il s'agit de l'ordre dans lequel le gestionnaire de négociation de contenu Spring essaiera d'utiliser ces trois stratégies. Et si aucun de ceux-ci n'est activé, nous pouvons spécifier un repli sur un type de contenu par défaut.

2. Stratégies de négociation de contenu

Commençons par les dépendances nécessaires - nous travaillons avec des représentations JSON et XML, donc pour cet article, nous utiliserons Jackson pour JSON:


    com.fasterxml.jackson.core
    jackson-core
    2.7.2


    com.fasterxml.jackson.core
    jackson-databind
    2.7.2

Pour la prise en charge XML, nous pouvons utiliser JAXB, XStream ou la prise en charge Jackson-XML plus récente.

Puisque nous avons expliqué l’utilisation de l’en-têteAccept dansan earlier article onHttpMessageConverters,, concentrons-nous sur les deux premières stratégies en profondeur.

3. La stratégie de suffixe d'URL

Par défaut, cette stratégie est désactivée, mais l'infrastructure peut rechercher une extension de chemin directement à partir de l'URL afin de déterminer le type de contenu en sortie.

Avant d'entrer dans les configurations, jetons un coup d'œil à un exemple. Nous avons l'implémentation suivante d'une méthode API simple dans un contrôleur Spring typique:

@RequestMapping(
  value = "/employee/{id}",
  produces = { "application/json", "application/xml" },
  method = RequestMethod.GET)
public @ResponseBody Employee getEmployeeById(@PathVariable long id) {
    return employeeMap.get(id);
}

Appelons-le en utilisant l'extension JSON pour spécifier le type de média de la ressource:

curl http://localhost:8080/spring-mvc-basics/employee/10.json

Voici ce que nous pourrions obtenir si nous utilisons une extension JSON:

{
    "id": 10,
    "name": "Test Employee",
    "contactNumber": "999-999-9999"
}

Et voici à quoi ressemblera la requête - réponse avec XML:

curl http://localhost:8080/spring-mvc-basics/employee/10.xml

Le corps de la réponse:


    999-999-9999
    10
    Test Employee

Now:

Maintenantif we do not use any extension ou utilisez-en un qui n'est pas configuré - le type de contenu par défaut sera retourné:

curl http://localhost:8080/spring-mvc-basics/employee/10

Voyons maintenant la mise en place de cette stratégie, à la fois avec des configurations Java et XML.

3.1. Configuration Java

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(true).
    favorParameter(false).
    ignoreAcceptHeader(true).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON);
}

Passons en revue les détails.

Tout d'abord, nous activons la stratégie d'extensions de chemin.

Ensuite, nous désactivons la stratégie de paramètre d'URL ainsi que la stratégie d'en-têteAccept, car nous souhaitons nous fier uniquement à la méthode d'extension de chemin pour déterminer le type de contenu.

Nous désactivons ensuite le Java Activation Framework; JAF peut être utilisé comme mécanisme de secours pour sélectionner le format de sortie si la demande entrante ne correspond à aucune des stratégies que nous avons configurées. Nous le désactivons, car nous allons configurer JSON comme type de contenu par défaut.

Et enfin - nous configurons JSON pour être le fichier par défaut. Cela signifie que si aucune des deux stratégies ne correspond, toutes les demandes entrantes seront mappées vers une méthode de contrôleur prenant en charge JSON.

3.2. Configuration XML

Jetons également un coup d'œil à la même configuration exacte, en utilisant uniquement XML:


    
    
    
    
    

4. La stratégie des paramètres d'URL

Nous avons utilisé des extensions de chemin dans la section précédente - configurons maintenant Spring MVC pour utiliser un paramètre de chemin.

Nous pouvons activer cette stratégie en définissant la valeur de la propriétéfavorParameter sur true.

Voyons rapidement comment cela fonctionnerait avec notre exemple précédent:

curl http://localhost:8080/spring-mvc-basics/employee/10?mediaType=json

Et voici ce que sera le corps de la réponse JSON:

{
    "id": 10,
    "name": "Test Employee",
    "contactNumber": "999-999-9999"
}

Si nous utilisons un paramètre XML, la sortie sera sous forme XML:

curl http://localhost:8080/spring-mvc-basics/employee/10?mediaType=xml

Le corps de la réponse:


    999-999-9999
    10
    Test Employee

Maintenant, faisons la configuration - encore une fois, en utilisant d'abord Java, puis XML.

4.1. Configuration Java

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(false).
    favorParameter(true).
    parameterName("mediaType").
    ignoreAcceptHeader(true).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON).
    mediaType("xml", MediaType.APPLICATION_XML).
    mediaType("json", MediaType.APPLICATION_JSON);
}

Lisons cette configuration.

Tout d'abord, bien sûr, l'extension de chemin et les stratégies d'en-têteAccept sont désactivées (ainsi que JAF).

Le reste de la configuration est la même.

4.2. Configuration XML


    
    
    
    
    
    

    
        
            
            
        
    

Nous pouvons également avoirboth strategies (extension and parameter) enabled en même temps:

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(true).
    favorParameter(true).
    parameterName("mediaType").
    ignoreAcceptHeader(true).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON).
    mediaType("xml", MediaType.APPLICATION_XML).
    mediaType("json", MediaType.APPLICATION_JSON);
}

Dans ce cas, Spring recherchera d'abord l'extension de chemin, si elle n'est pas présente, le paramètre path sera recherché. Et si les deux ne sont pas disponibles dans la demande d'entrée, le type de contenu par défaut sera renvoyé.

5. La stratégie d'en-têteAccept

Si l'en-têteAccept est activé, Spring MVC recherchera sa valeur dans la requête entrante pour déterminer le type de représentation.

Nous devons définir la valeur deignoreAcceptHeader sur false pour activer cette approche et nous désactivons les deux autres stratégies juste pour savoir que nous ne comptons que sur l'en-têteAccept.

5.1. Configuration Java

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(true).
    favorParameter(false).
    parameterName("mediaType").
    ignoreAcceptHeader(false).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON).
    mediaType("xml", MediaType.APPLICATION_XML).
    mediaType("json", MediaType.APPLICATION_JSON);
}

5.2. Configuration XML


    
    
    
    
    
    

    
        
            
            
        
    

Enfin, nous devons activer le gestionnaire de négociation de contenu en le connectant à la configuration générale:

6. Conclusion

Et nous avons terminé. Nous avons examiné le fonctionnement de la négociation de contenu dans Spring MVC et nous nous sommes concentrés sur quelques exemples de configuration permettant d'utiliser différentes stratégies pour déterminer le type de contenu.

L'implémentation complète de cet article se trouve dansthe github project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.