Spring ResponseEntity verwenden, um die HTTP-Antwort zu ändern

Verwenden von Spring ResponseEntity zum Bearbeiten der HTTP-Antwort

1. Einführung

Mit Spring haben wir normalerweise viele Möglichkeiten, um dasselbe Ziel zu erreichen, einschließlich der Feinabstimmung von HTTP-Antworten.

In diesem kurzen Tutorial erfahren Sie, wie Sie den Hauptteil, den Status und die Header einer HTTP-Antwort mithilfe vonResponseEntity festlegen.

Weitere Lektüre:

Abrufen und Überprüfen von Antwortdaten mit REST-Sicherheit

Sehen Sie sich an, wie Sie mit REST-Assured die Antwort von einem REST-Endpunkt validieren und extrahieren

Read more

Verwenden von Spring @ResponseStatus zum Festlegen des HTTP-Statuscodes

Sehen Sie sich die Anmerkung @ResponseStatus an und erfahren Sie, wie Sie damit den Antwortstatuscode festlegen.

Read more

2. ResponseEntity

ResponseEntityrepresents the whole HTTP response: status code, headers, and body. Aus diesem Grund können wir damit die HTTP-Antwort vollständig konfigurieren.

Wenn wir es verwenden möchten, müssen wir es vom Endpunkt zurückgeben. Der Frühling kümmert sich um den Rest.

ResponseEntity ist ein generischer Typ. Daher können wir jeden Typ als Antworttext verwenden:

@GetMapping("/hello")
ResponseEntity hello() {
    return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}

Da wir den Antwortstatus programmgesteuert angeben, können wir für verschiedene Szenarien unterschiedliche Statuscodes zurückgeben:

@GetMapping("/age")
ResponseEntity age(
  @RequestParam("yearOfBirth") int yearOfBirth) {

    if (isInFuture(yearOfBirth)) {
        return new ResponseEntity<>(
          "Year of birth cannot be in the future",
          HttpStatus.BAD_REQUEST);
    }

    return new ResponseEntity<>(
      "Your age is " + calculateAge(yearOfBirth),
      HttpStatus.OK);
}

Zusätzlich können wir HTTP-Header setzen:

@GetMapping("/customHeader")
ResponseEntity customHeader() {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "foo");

    return new ResponseEntity<>(
      "Custom header set", headers, HttpStatus.OK);
}

WeiterhinResponseEntityprovides two nested builder interfaces:HeadersBuilder und seine UnterschnittstelleBodyBuilder. Daher können wir über die statischen Methoden vonResponseEntity auf ihre Fähigkeiten zugreifen.

Der einfachste Fall ist eine Antwort mit einem Body und einem HTTP 200-Antwortcode:

@GetMapping("/hello")
ResponseEntity hello() {
    return ResponseEntity.ok("Hello World!");
}

Für die gängigsten HTTP-Statuscodes erhalten wir statische Methoden:

BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder noContent();
HeadersBuilder notFound();
BodyBuilder ok();

Darüber hinaus können wir die MethodenBodyBuilder status(HttpStatus status) undBodyBuilder status(int status) verwenden, um einen beliebigen HTTP-Status festzulegen.

Schließlich können wir mitResponseEntity<T> BodyBuilder.body(T body) den HTTP-Antworttext festlegen:

@GetMapping("/age")
ResponseEntity age(@RequestParam("yearOfBirth") int yearOfBirth) {
    if (isInFuture(yearOfBirth)) {
        return ResponseEntity.badRequest()
            .body("Year of birth cannot be in the future");
    }

    return ResponseEntity.status(HttpStatus.OK)
        .body("Your age is " + calculateAge(yearOfBirth));
}

Wir können auch benutzerdefinierte Header setzen:

@GetMapping("/customHeader")
ResponseEntity customHeader() {
    return ResponseEntity.ok()
        .header("Custom-Header", "foo")
        .body("Custom header set");
}

Daher gibtBodyBuilder.body()ResponseEntity anstelle vonBodyBuilder, zurück, es sollte der letzte Aufruf sein.

Beachten Sie, dass wir mitHeaderBuilder keine Eigenschaften des Antwortkörpers festlegen können.

Bei der Rückgabe des ObjektsResponseEntity<T>vom Controller wird möglicherweise eine Ausnahme oder ein Fehler bei der Verarbeitung der Anforderung angezeigt, und wir möchtenreturn error-related information to the user represented as some other type let’s say E.

Spring 3.2 bietet Unterstützung für ein globales@ExceptionHandler with the new @ControllerAdvice annotation, das diese Art von Szenarien behandelt. Ausführliche Informationen finden Sie in unserem vorhandenen Artikelhere.

While ResponseEntity is very powerful, we shouldn’t overuse it. In einfachen Fällen gibt es andere Optionen, die unseren Anforderungen entsprechen und zu einem viel saubereren Code führen.

3. Alternativen

3.1. @ResponseBody

In klassischen Spring MVC-Anwendungen geben Endpunkte normalerweise gerenderte HTML-Seiten zurück. Manchmal müssen wir nur die tatsächlichen Daten zurückgeben, wenn wir beispielsweise den Endpunkt mit AJAX verwenden.

In solchen Fällen können wir die Request-Handler-Methode mit@ResponseBody undSpring treats the result value of the method as the HTTP response body selbst markieren.

Für weitere Informationenthis article is a good place to start.

3.2. @ResponseStatus

Wenn ein Endpunkt erfolgreich zurückgegeben wird, gibt Spring eine HTTP 200-Antwort (OK) aus. Wenn der Endpunkt eine Ausnahme auslöst, sucht Spring nach einem Ausnahmehandler, der angibt, welcher HTTP-Status verwendet werden soll.

Wir können diese Methoden mit @ResponseStatus markieren. Daher Federreturns with a custom HTTP status.

Weitere Beispiele finden Sie in unserem Artikel übercustom status codes.

3.3. Bearbeiten Sie die Antwort direkt

Mit Spring können wir auch direkt auf dasjavax.servlet.http.HttpServletResponse-Objekt zugreifen. wir müssen es nur als Methodenargument deklarieren:

@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
    response.setHeader("Custom-Header", "foo");
    response.setStatus(200);
    response.getWriter().println("Hello World!");
}

Da Spring über der zugrunde liegenden Implementierung Abstraktionen und zusätzliche Funktionen bereitstellt,we shouldn’t manipulate the response this way.

4. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten mit ihren Vor- und Nachteilen zur Manipulation der HTTP-Antwort im Frühjahr vorgestellt.

Wie üblich sind die Beispiele inover on GitHub verfügbar.