Spring MVC Content Negotiation

1. Übersicht

Dieser Artikel beschreibt, wie Sie die Inhaltsverhandlung in einem Spring MVC-Projekt implementieren.

Im Allgemeinen gibt es drei Optionen, um den Medientyp einer Anforderung zu bestimmen:

  • Verwenden von URL-Suffixen (Erweiterungen) in der Anforderung (z. B. .xml / .json )
  • Verwenden des URL-Parameters in der Anforderung (z . B. ? Format = json )
  • Verwenden des Accept- Headers in der Anforderung

Standardmäßig ist dies die Reihenfolge, in der der Spring Content Negotiation Manager versucht, diese drei Strategien zu verwenden. Und wenn keines davon aktiviert ist, können wir einen Fallback auf einen Standardinhaltstyp angeben.

2. Strategien für die Aushandlung von Inhalten

Beginnen wir mit den erforderlichen Abhängigkeiten - wir arbeiten mit JSON- und XML-Darstellungen. In diesem Artikel verwenden wir Jackson für JSON:

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

Für die XML-Unterstützung können wir entweder JAXB, XStream oder die neuere Jackson-XML-Unterstützung verwenden.

Da wir die Verwendung des Accept- Headers in einem früheren Artikel über HttpMessageConverters erläutert haben, konzentrieren wir uns eingehend auf die ersten beiden Strategien.

3. Die URL-Suffix-Strategie

Standardmäßig ist diese Strategie deaktiviert, aber das Framework kann direkt über die URL nach einer Pfaderweiterung suchen, um den Ausgabeinhaltstyp zu bestimmen.

Bevor wir uns mit Konfigurationen befassen, werfen wir einen kurzen Blick auf ein Beispiel. Wir haben die folgende einfache API-Methodenimplementierung in einem typischen Spring-Controller:

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

Rufen wir es auf, indem wir die JSON-Erweiterung verwenden, um den Medientyp der Ressource anzugeben:

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

Folgendes erhalten wir möglicherweise zurück, wenn wir eine JSON-Erweiterung verwenden:

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

Und so sieht die Anfrage-Antwort mit XML aus:

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

Der Antwortkörper:

 999-999-9999 10 Test Employee 

Nun, wenn wir keine Erweiterung verwenden oder die Verwendung eines , das nicht konfiguriert ist, wird der Standard - Inhaltstyp zurückgegeben:

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

Lassen Sie uns nun einen Blick auf die Einrichtung dieser Strategie werfen - sowohl mit Java- als auch mit XML-Konfigurationen.

3.1. Java-Konfiguration

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

Lassen Sie uns die Details durchgehen.

Zunächst aktivieren wir die Strategie zur Pfaderweiterung. Erwähnenswert ist auch, dass ab Spring Framework 5.2.4 die favorPathExtension- Methode (boolean) veraltet ist, um die Verwendung von Pfaderweiterungen für Inhaltsverhandlungen zu verhindern.

Dann deaktivieren wir die URL-Parameterstrategie sowie die Accept- Header-Strategie, da wir uns nur auf die Pfaderweiterungsmethode zur Bestimmung des Inhaltstyps verlassen möchten.

Wir deaktivieren dann das Java Activation Framework. JAF kann als Fallback-Mechanismus zur Auswahl des Ausgabeformats verwendet werden, wenn die eingehende Anforderung keiner der von uns konfigurierten Strategien entspricht. Wir deaktivieren es, weil wir JSON als Standardinhaltstyp konfigurieren werden. Bitte beachten Sie, dass die useJaf () -Methode ab Spring Framework 5 veraltet ist .

Und schließlich - wir richten JSON als Standard ein. Das heißt, wenn keine der beiden Strategien übereinstimmt, werden alle eingehenden Anforderungen einer Controller-Methode zugeordnet, die JSON bedient.

3.2. XML-Konfiguration

Lassen Sie uns auch einen kurzen Blick auf dieselbe genaue Konfiguration werfen, die nur XML verwendet:

4. Die URL-Parameterstrategie

Wir haben im vorherigen Abschnitt Pfaderweiterungen verwendet. Richten Sie nun Spring MVC so ein, dass ein Pfadparameter verwendet wird.

Wir können diese Strategie aktivieren, indem wir den Wert der favorParameter- Eigenschaft auf true setzen.

Lassen Sie uns einen kurzen Blick darauf werfen, wie dies mit unserem vorherigen Beispiel funktionieren würde:

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

Und hier ist der JSON-Antworttext:

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

Wenn wir den XML-Parameter verwenden, erfolgt die Ausgabe in XML-Form:

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

Der Antwortkörper:

 999-999-9999 10 Test Employee 

Jetzt machen wir die Konfiguration - wieder zuerst mit Java und dann mit XML.

4.1. Java-Konfiguration

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

Lesen wir diese Konfiguration durch.

Zunächst sind natürlich die Pfaderweiterung und die Accept- Header-Strategien deaktiviert (ebenso wie JAF).

Der Rest der Konfiguration ist der gleiche.

4.2. XML-Konfiguration

Außerdem können beide Strategien (Erweiterung und Parameter) gleichzeitig aktiviert werden:

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 diesem Fall sucht Spring zuerst nach der Pfaderweiterung. Wenn diese nicht vorhanden ist, sucht sie nach dem Pfadparameter. Und wenn beide in der Eingabeanforderung nicht verfügbar sind, wird der Standardinhaltstyp zurückgegeben.

5. Die Accept Header-Strategie

Wenn der Accept- Header aktiviert ist, sucht Spring MVC in der eingehenden Anforderung nach seinem Wert, um den Darstellungstyp zu bestimmen.

Wir müssen den Wert von ignoreAcceptHeader auf false setzen, um diesen Ansatz zu aktivieren, und wir deaktivieren die beiden anderen Strategien, damit wir wissen, dass wir uns nur auf den Accept- Header verlassen.

5.1. Java-Konfiguration

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. XML-Konfiguration

Schließlich müssen wir den Content Negotiation Manager einschalten, indem wir ihn in die Gesamtkonfiguration einfügen:

6. Fazit

Und wir sind fertig. Wir haben uns angesehen, wie die Inhaltsverhandlung in Spring MVC funktioniert, und uns auf einige Beispiele konzentriert, wie diese eingerichtet werden können, um verschiedene Strategien zur Bestimmung des Inhaltstyps zu verwenden.

Die vollständige Implementierung dieses Artikels finden Sie auf GitHub.