Spring JSON-P avec Jackson

Haut REST

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> DÉCOUVREZ LE COURS Jackson Top

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Vue d'ensemble

Si vous avez développé quelque chose sur le Web, vous êtes conscient de la contrainte de politique de même origine que les navigateurs ont lorsqu'ils traitent des requêtes AJAX. Le simple aperçu de la contrainte est que toute demande provenant d'un domaine, d'un schéma ou d'un port différent ne sera pas autorisée.

Une façon d' assouplir cette restriction du navigateur lorsque vous travaillez avec des données JSON consiste à utiliser JSON avec remplissage (JSON-P).

Cet article décrit la prise en charge de Spring pour l'utilisation des données JSON-P - avec l'aide de AbstractJsonpResponseBodyAdvice .

2. JSON-P en action

La politique de la même origine n'est pas imposée au tag, permettant aux scripts d'être chargés sur différents domaines. La technique JSON-P en profite en passant la réponse JSON comme argument de la fonction javascript.

2.1. Préparation

Dans nos exemples, nous utiliserons cette classe Company simple :

public class Company { private long id; private String name; // standard setters and getters } 

Cette classe liera les paramètres de la demande et sera renvoyée par le serveur en tant que représentation JSON.

La méthode Controller est également une implémentation simple - renvoyant l' instance Company :

@RestController public class CompanyController { @RequestMapping(value = "/companyRest", produces = MediaType.APPLICATION_JSON_VALUE) public Company getCompanyRest() { Company company = new Company(1, "Xpto"); return company; } }

Du côté client, nous pouvons utiliser la bibliothèque jQuery pour créer et envoyer une requête AJAX:

$.ajax({ url: '//localhost:8080/spring-mvc-java/companyRest', data: { format: 'json' }, type: 'GET', ... });

Considérez une requête AJAX par rapport à l'URL suivante:

//localhost:8080/spring-mvc-java/companyRest 

La réponse du serveur serait la suivante:

{"id":1,"name":"Xpto"}

Comme la demande a été envoyée sur le même schéma, le même domaine et le même port, la réponse ne sera pas bloquée et les données JSON seront autorisées par le navigateur.

2.2. Demande d’origine croisée

En modifiant l'URL de la demande en:

//127.0.0.1:8080/spring-mvc-java/companyRest 

la réponse sera bloquée par le navigateur, en raison d'une demande envoyée de localhost à 127.0.0.1 qui est considéré comme un domaine différent et présente une violation de la politique de même origine.

Avec JSON-P, nous pouvons ajouter un paramètre de rappel à la requête:

//127.1.1.1:8080/spring-mvc-java/companyRest?callback=getCompanyData 

Du côté client, c'est aussi simple que d'ajouter les paramètres suivants à la requête AJAX:

$.ajax({ ... jsonpCallback:'getCompanyData', dataType: 'jsonp', ... });

Le getCompanyData sera la fonction appelée lorsque la réponse est reçue.

Si le serveur formate la réponse comme suit:

getCompanyData({"id":1,"name":"Xpto"}); 

les navigateurs ne le bloqueront pas, car il traitera la réponse comme un script négocié et convenu entre le client et le serveur en raison de la correspondance avec getCompanyData dans la requête et la réponse.

3. Annotation @ControllerAdvice

Les beans annotés avec @ControllerAdvice peuvent aider tout ou un sous-ensemble spécifique de contrôleurs et sont utilisés pour encapsuler le comportement transversal partagé entre différents contrôleurs. Les modèles d'utilisation typiques sont liés à la gestion des exceptions, à l'ajout d'attributs aux modèles ou à l'enregistrement des classeurs.

À partir de Spring 4.1 , @ControllerAdvice est capable d'enregistrer les implémentations de l' interface ResponseBodyAdvice qui permet de changer la réponse après son retour par une méthode de contrôleur mais avant d'être écrite par un convertisseur approprié.

4. Modification de la réponse à l'aide de AbstractJsonpResponseBodyAdvice

À partir de Spring 4.1 , nous avons désormais accès à la classe AbstractJsonpResponseBodyAdvice - qui formate la réponse selon les normes JSON-P.

Cette section explique comment mettre la classe de base en jeu et modifier la réponse sans apporter de modifications aux contrôleurs existants.

Afin d'activer le support Spring pour JSON-P, commençons par la configuration:

@ControllerAdvice public class JsonpControllerAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpControllerAdvice() { super("callback"); } } 

The support is made using the AbstractJsonpResponseBodyAdvice class. The key passed on the super method is the one that will be used in URL requesting JSON-P data.

With this controller advice, we automatically convert the response to JSON-P.

5. JSON-P With Spring in Practice

With the previously discussed configuration in place, we are able to make our REST applications respond with JSON-P. In the following example, we will return company's data, so our AJAX request URL should be something like this:

//127.0.0.1:8080/spring-mvc-java/companyRest?callback=getCompanyData 

As a result of the previous configuration, the response will look as follows:

getCompanyData({"id":1,"name":"Xpto"});

As discussed, the response in this format will not get blocked despite originating from a different domain.

Le JsonpControllerAdvice peut facilement être appliqué à toute méthode qui renvoie une réponse annotée avec @ResponseBody et ResponseEntity .

Il devrait y avoir une fonction avec le même nom passé dans le rappel, getCompanyData , pour gérer toutes les réponses .

6. Conclusion

Cet article rapide montre comment un travail autrement fastidieux de formatage de la réponse pour tirer parti de JSON-P est simplifié à l'aide de la nouvelle fonctionnalité de Spring 4.1.

L'implémentation des exemples et des extraits de code se trouve dans ce projet GitHub.

REST bas

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> DÉCOUVREZ LE COURS Jackson bottom

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS