Negoziazione dei contenuti Spring MVC

1. Panoramica

Questo articolo descrive come implementare la negoziazione del contenuto in un progetto Spring MVC.

In genere, sono disponibili tre opzioni per determinare il tipo di supporto di una richiesta:

  • Utilizzo di suffissi URL (estensioni) nella richiesta (ad esempio .xml / .json )
  • Utilizzo del parametro URL nella richiesta (ad es. ? Format = json )
  • Utilizzo dell'intestazione Accept nella richiesta

Per impostazione predefinita, questo è l'ordine in cui il gestore della negoziazione dei contenuti Spring tenterà di utilizzare queste tre strategie. E se nessuno di questi è abilitato, possiamo specificare un fallback a un tipo di contenuto predefinito.

2. Strategie di negoziazione dei contenuti

Cominciamo con le dipendenze necessarie: stiamo lavorando con rappresentazioni JSON e XML, quindi per questo articolo useremo Jackson per JSON:

 com.fasterxml.jackson.core jackson-core 2.10.2   com.fasterxml.jackson.core jackson-databind 2.10.2  

Per il supporto XML, possiamo utilizzare JAXB, XStream o il più recente supporto Jackson-XML.

Poiché abbiamo spiegato l'uso dell'intestazione Accept in un articolo precedente su HttpMessageConverters, concentriamoci sulle prime due strategie in modo approfondito.

3. La strategia del suffisso URL

Per impostazione predefinita, questa strategia è disabilitata, ma il framework può verificare la presenza di un'estensione del percorso direttamente dall'URL per determinare il tipo di contenuto di output.

Prima di entrare nelle configurazioni, diamo una rapida occhiata a un esempio. Abbiamo la seguente semplice implementazione del metodo API in un tipico controller Spring:

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

Richiamiamolo facendo uso dell'estensione JSON per specificare il tipo di supporto della risorsa:

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

Ecco cosa potremmo ottenere se usiamo un'estensione JSON:

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

Ed ecco come apparirà la richiesta-risposta con XML:

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

Il corpo della risposta:

 999-999-9999 10 Test Employee 

Ora, se non usiamo alcuna estensione o ne usiamo una non configurata, verrà restituito il tipo di contenuto predefinito:

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

Diamo ora un'occhiata all'impostazione di questa strategia, con configurazioni sia Java che XML.

3.1. Configurazione Java

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

Andiamo oltre i dettagli.

Innanzitutto, stiamo abilitando la strategia delle estensioni di percorso. Vale anche la pena ricordare che a partire da Spring Framework 5.2.4, il metodo favorPathExtension (booleano) è deprecato per scoraggiare l'uso di estensioni di percorso per la negoziazione dei contenuti.

Quindi, stiamo disabilitando la strategia del parametro URL e la strategia di intestazione Accetta , perché vogliamo fare affidamento solo sul modo dell'estensione del percorso per determinare il tipo di contenuto.

Stiamo quindi disattivando Java Activation Framework; JAF può essere utilizzato come meccanismo di fallback per selezionare il formato di output se la richiesta in arrivo non corrisponde a nessuna delle strategie che abbiamo configurato. Lo stiamo disabilitando perché configureremo JSON come tipo di contenuto predefinito. Si noti che il metodo useJaf () è deprecato a partire da Spring Framework 5 .

Infine, stiamo configurando JSON come predefinito. Ciò significa che se nessuna delle due strategie viene abbinata, tutte le richieste in arrivo verranno mappate a un metodo del controller che serve JSON.

3.2. Configurazione XML

Diamo anche una rapida occhiata alla stessa esatta configurazione, utilizzando solo XML:

4. La strategia del parametro URL

Abbiamo utilizzato le estensioni di percorso nella sezione precedente: ora configuriamo Spring MVC per utilizzare un parametro di percorso.

È possibile abilitare questa strategia impostando il valore della proprietà favorParameter su true.

Diamo una rapida occhiata a come funzionerebbe con il nostro esempio precedente:

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

Ed ecco quale sarà il corpo della risposta JSON:

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

Se usiamo il parametro XML, l'output sarà in formato XML:

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

Il corpo della risposta:

 999-999-9999 10 Test Employee 

Ora facciamo la configurazione - di nuovo, prima usando Java e poi XML.

4.1. Configurazione 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); } 

Leggiamo questa configurazione.

Innanzitutto, ovviamente, l'estensione del percorso e le strategie di intestazione Accept sono disabilitate (così come JAF).

The rest of the configuration is the same.

4.2. XML Configuration

Also, we can have both strategies (extension and parameter) enabled at the same time:

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); }

In this case, Spring will look for path extension first, if that is not present then will look for path parameter. And if both of these are not available in the input request, then the default content type will be returned back.

5. The Accept Header Strategy

If the Accept header is enabled, Spring MVC will look for its value in the incoming request to determine the representation type.

Dobbiamo impostare il valore di ignoreAcceptHeader su false per abilitare questo approccio e disabilitiamo le altre due strategie solo per sapere che ci basiamo solo sull'intestazione Accept .

5.1. Configurazione 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. Configurazione XML

Infine, dobbiamo attivare il gestore della negoziazione del contenuto inserendolo nella configurazione generale:

6. Conclusione

E abbiamo finito. Abbiamo esaminato come funziona la negoziazione del contenuto in Spring MVC e ci siamo concentrati su alcuni esempi di impostazione per utilizzare varie strategie per determinare il tipo di contenuto.

L'implementazione completa di questo articolo può essere trovata su GitHub.