Spring JSON-P con Jackson

REST Top

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> GUARDA IL CORSO Jackson Top

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO

1. Panoramica

Se hai sviluppato qualcosa sul Web, sei a conoscenza del vincolo della politica della stessa origine che i browser hanno quando gestiscono le richieste AJAX. La semplice panoramica del vincolo è che qualsiasi richiesta proveniente da un diverso dominio, schema o porta non sarà consentita.

Un modo per ridurre questa restrizione del browser quando si lavora con dati JSON è usare JSON con riempimento (JSON-P).

Questo articolo discute il supporto di Spring per lavorare con i dati JSON-P, con l'aiuto di AbstractJsonpResponseBodyAdvice .

2. JSON-P in azione

La politica della stessa origine non è imposta su tag, consentendo il caricamento degli script su diversi domini. La tecnica JSON-P ne sfrutta i vantaggi passando la risposta JSON come argomento della funzione javascript.

2.1. Preparazione

Nei nostri esempi, useremo questa semplice classe Company :

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

Questa classe vincolerà i parametri della richiesta e verrà restituita dal server come rappresentazione JSON.

Anche il metodo Controller è un'implementazione semplice, che restituisce l' istanza Company :

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

Sul lato client possiamo utilizzare la libreria jQuery per creare e inviare una richiesta AJAX:

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

Considera una richiesta AJAX contro il seguente URL:

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

La risposta dal server sarebbe la seguente:

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

Poiché la richiesta è stata inviata sullo stesso schema, dominio e porta, la risposta non verrà bloccata e i dati JSON saranno consentiti dal browser.

2.2. Richiesta Cross-Origin

Modificando l'URL della richiesta in:

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

la risposta verrà bloccata dal browser, a causa della richiesta inviata da localhost a 127.0.0.1 che è considerato un dominio diverso e presenta una violazione della policy della stessa origine.

Con JSON-P, siamo in grado di aggiungere un parametro di callback alla richiesta:

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

Sul lato client è facile come aggiungere i seguenti parametri alla richiesta AJAX:

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

Il getCompanyData sarà la funzione chiamata quando si riceve una risposta.

Se il server formatta la risposta come segue:

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

i browser non la bloccheranno, poiché tratteranno la risposta come uno script negoziato e concordato tra il client e il server in virtù della corrispondenza di getCompanyData sia nella richiesta che nella risposta.

3. Annotazione @ControllerAdvice

I bean annotati con @ControllerAdvice sono in grado di assistere tutti o un sottoinsieme specifico di controller e vengono utilizzati per incapsulare il comportamento trasversale condiviso tra controller diversi. I modelli di utilizzo tipici sono correlati alla gestione delle eccezioni, all'aggiunta di attributi ai modelli o alla registrazione di raccoglitori.

A partire dalla Spring 4.1 , @ControllerAdvice è in grado di registrare le implementazioni dell'interfaccia ResponseBodyAdvice che permette di modificare la risposta dopo che è stata restituita da un metodo del controller ma prima di essere scritta da un opportuno convertitore.

4. Modifica della risposta utilizzando AbstractJsonpResponseBodyAdvice

Sempre a partire dalla Spring 4.1 , ora abbiamo accesso alla classe AbstractJsonpResponseBodyAdvice , che formatta la risposta secondo gli standard JSON-P.

Questa sezione spiega come mettere in gioco la classe base e modificare la risposta senza apportare modifiche ai controller esistenti.

Per abilitare il supporto Spring per JSON-P, iniziamo con la configurazione:

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

Il supporto viene effettuato utilizzando la classe AbstractJsonpResponseBodyAdvice . La chiave passata al super metodo è quella che verrà utilizzata nell'URL che richiede dati JSON-P.

Con questo consiglio del controller, convertiamo automaticamente la risposta in JSON-P.

5. JSON-P con la primavera in pratica

Con la configurazione precedentemente discussa in atto, siamo in grado di far rispondere le nostre applicazioni REST con JSON-P. Nell'esempio seguente, restituiremo i dati dell'azienda, quindi il nostro URL di richiesta AJAX dovrebbe essere qualcosa del genere:

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

Come risultato della configurazione precedente, la risposta sarà la seguente:

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

Come discusso, la risposta in questo formato non verrà bloccata nonostante provenga da un dominio diverso.

Il JsonpControllerAdvice può essere facilmente applicato a qualsiasi metodo che restituisce una risposta annotato con @ResponseBody e ResponseEntity .

Ci dovrebbe essere una funzione con lo stesso nome passata nel callback, getCompanyData , per la gestione di tutte le risposte .

6. Conclusione

Questo rapido articolo mostra come un lavoro altrimenti noioso di formattazione della risposta per sfruttare JSON-P è semplificato utilizzando la nuova funzionalità in Spring 4.1.

L'implementazione degli esempi e dei frammenti di codice può essere trovata in questo progetto GitHub.

REST fondo

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> GUARDA IL CORSO Jackson bottom

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO