Verwenden von Spring ResponseEntity zum Bearbeiten der HTTP-Antwort

1. Einleitung

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 Text, den Status und die Header einer HTTP-Antwort mithilfe von ResponseEntity festlegen .

2. ResponseEntity

ResponseEntity repräsentiert die gesamte HTTP-Antwort: Statuscode, Header und Body . Infolgedessen 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. Folglich können wir jeden Typ als Antwortkörper verwenden:

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

Da wir den Antwortstatus programmgesteuert angeben, können wir mit unterschiedlichen Statuscodes für verschiedene Szenarien zurückkehren:

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

Darüber hinaus bietet ResponseEntity zwei verschachtelte Builder-Schnittstellen : HeadersBuilder und seine Subschnittstelle BodyBuilder . Daher können wir über die statischen Methoden von ResponseEntity auf ihre Funktionen 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 beliebtesten 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 Methoden BodyBuilder-Status (HttpStatus-Status) und BodyBuilder-Status (int-Status) verwenden, um einen beliebigen HTTP-Status festzulegen .

Schließlich können wir mit ResponseEntity 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 festlegen:

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

Da BodyBuilder.body () anstelle von BodyBuilder eine ResponseEntity zurückgibt, sollte dies der letzte Aufruf sein.

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

Während der Rückkehr ResponseEntity Objekt von der Steuerung, könnten wir eine Ausnahme oder Fehler erhalten , während der Verarbeitung der Anfrage und möchte fehlerbezogene Informationen an den Benutzer als eine andere Art dargestellt zurückzukehren, lassen Sie uns E sagen .

Spring 3.2 bietet Unterstützung für einen globalen @ExceptionHandler mit der neuen Annotation @ControllerAdvice , die diese Art von Szenarien behandelt. Ausführliche Informationen finden Sie in unserem vorhandenen Artikel hier.

Obwohl ResponseEntity sehr leistungsfähig ist, sollten wir es nicht überbeanspruchen. In einfachen Fällen gibt es andere Optionen, die unsere Anforderungen erfüllen 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. Zum Beispiel, wenn wir den Endpunkt mit AJAX verwenden.

In solchen Fällen können wir die Request-Handler-Methode mit @ResponseBody markieren , und Spring behandelt den Ergebniswert der Methode als den HTTP-Antworttext selbst.

Für weitere Informationen ist dieser Artikel ein guter Anfang.

3.2. @ResponseStatus

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

Wir können diese Methoden mit @ResponseStatus markieren. Daher gibt Spring mit einem benutzerdefinierten HTTP-Status zurück .

Weitere Beispiele finden Sie in unserem Artikel über benutzerdefinierte Statuscodes.

3.3. Bearbeiten Sie die Antwort direkt

Mit Spring können wir auch direkt auf das Objekt javax.servlet.http.HttpServletResponse 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 bietet, sollten wir die Antwort nicht auf diese Weise manipulieren .

4. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten zur Manipulation der HTTP-Antwort im Frühjahr erörtert und deren Vor- und Nachteile untersucht.

Wie üblich sind die Beispiele auf GitHub verfügbar.