Spring JSON-P mit Jackson

Spring JSON-P mit Jackson

1. Überblick

Wenn Sie etwas im Web entwickelt haben, wissen Sie, dass die Browser vonthe same-origin policy constraintüber AJAX-Anforderungen verfügen. Die einfache Übersicht über die Einschränkung besteht darin, dass Anforderungen, die von einer anderen Domäne, einem anderen Schema oder einem anderen Port stammen, nicht zulässig sind.

Eine Möglichkeit zurelax this browser restriction beim Arbeiten mit JSON-Daten ist die Verwendung von JSON mit Auffüllung (JSON-P).

In diesem Artikel wird die Unterstützung von Spring für die Arbeit mit JSON-P-Daten erläutert - mithilfe vonAbstractJsonpResponseBodyAdvice.

2. JSON-P in Aktion

Die Richtlinie mit demselben Ursprung wird nicht für das<script>-Tag festgelegt, sodass Skripte über verschiedene Domänen geladen werden können. Die JSON-P-Technik nutzt dies aus, indem sie die JSON-Antwort als Argument der Javascript-Funktion übergibt.

2.1. Vorbereitung

In unseren Beispielen verwenden wir diese einfacheCompany-Klasse:

public class Company {

    private long id;
    private String name;

    // standard setters and getters
}

Diese Klasse bindet die Anforderungsparameter und wird vom Server als JSON-Darstellung zurückgegeben.

Die Controller-Methode ist ebenfalls eine einfache Implementierung, die die Instanz vonCompanyzurückgibt:

@RestController
public class CompanyController {

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

Auf der Clientseite können wir die Bibliothek vonjQueryverwenden, um eine AJAX-Anfrage zu erstellen und zu senden:

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

Betrachten Sie eine AJAX-Anfrage unter der folgenden URL:

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

Die Antwort vom Server wäre die folgende:

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

Da die Anforderung für dasselbe Schema, dieselbe Domäne und denselben Port gesendet wurde, wird die Antwort nicht blockiert und JSON-Daten werden vom Browser zugelassen.

2.2. Ursprungsübergreifende Anfrage

Durch Ändern der Anforderungs-URL in:

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

Die Antwort wird vom Browser blockiert, da eine Anfrage vonlocalhost an127.0.0.1 gesendet wird, die als andere Domain betrachtet wird und einen Verstoß gegen die Richtlinie mit demselben Ursprung darstellt.

Mit JSON-P können wir der Anfrage einen Rückrufparameter hinzufügen:

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

Auf der Clientseite ist es so einfach wie das Hinzufügen der folgenden Parameter zur AJAX-Anforderung:

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

getCompanyData ist die Funktion, die aufgerufen wird, wenn die Antwort empfangen wird.

Wenn der Server die Antwort wie folgt formatiert:

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

Browser blockieren es nicht, da es die Antwort als ein zwischen dem Client und dem Server ausgehandeltes und vereinbartes Skript behandelt, da sowohl in der Anforderung als auch in der AntwortgetCompanyData übereinstimmen.

3. @ControllerAdvice Anmerkung

Die mit@ControllerAdvice versehenen Beans können alle oder eine bestimmte Teilmenge von Controllern unterstützen und werden verwendet, um das Querschnittsverhalten zu kapseln, das von verschiedenen Controllern gemeinsam genutzt wird. Typische Verwendungsmuster beziehen sich aufexception handling,adding attributes to models oder das Registrieren von Bindemitteln.

Starting with Spring 4.1,@ControllerAdvice kann die Implementierungen derResponseBodyAdvice-Schnittstelle registrieren, wodurch die Antwort geändert werden kann, nachdem sie von einer Steuerungsmethode zurückgegeben wurde, aber bevor sie von einem geeigneten Konverter geschrieben wurde.

4. Ändern der Antwort mitAbstractJsonpResponseBodyAdvice

Also starting with Spring 4.1 haben wir jetzt Zugriff auf die KlasseAbstractJsonpResponseBodyAdvice, die die Antwort gemäß den JSON-P-Standards formatiert.

In diesem Abschnitt wird erläutert, wie Sie die Basisklasse aktivieren und die Reaktion ändern, ohne Änderungen an den vorhandenen Controllern vorzunehmen.

Beginnen wir mit der Konfiguration, um die Spring-Unterstützung für JSON-P zu aktivieren:

@ControllerAdvice
public class JsonpControllerAdvice
  extends AbstractJsonpResponseBodyAdvice {

    public JsonpControllerAdvice() {
        super("callback");
    }
}

Die Unterstützung erfolgt mit der KlasseAbstractJsonpResponseBodyAdvice. Der Schlüssel, der an die super-Methode übergeben wird, wird in URLs verwendet, die JSON-P-Daten anfordern.

Mit diesem Controller-Hinweis wandeln wir die Antwort automatisch in JSON-P um.

5. JSON-P mit Frühling in der Praxis

Mit der zuvor beschriebenen Konfiguration können wir unsere REST-Anwendungen mit JSON-P reagieren lassen. Im folgenden Beispiel geben wir die Unternehmensdaten zurück, daher sollte unsere AJAX-Anforderungs-URL ungefähr so ​​lauten:

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

Infolge der vorherigen Konfiguration sieht die Antwort folgendermaßen aus:

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

Wie bereits erwähnt, wird die Antwort in diesem Format nicht blockiert, obwohl sie von einer anderen Domain stammt.

DieJsonpControllerAdvice können problemlos auf jede Methode angewendet werden, die eine mit@ResponseBody undResponseEntity kommentierte Antwort zurückgibt.

Im RückrufgetCompanyData sollte eine Funktion mit demselben Namen übergeben werden, um alle Antworten zu verarbeiten.

6. Fazit

Dieser kurze Artikel zeigt, wie die ansonsten mühsame Formatierung der Antwort zur Nutzung von JSON-P mithilfe der neuen Funktionalität in Spring 4.1 vereinfacht wird.

Die Implementierung der Beispiele und Codefragmente finden Sie inGitHub project.