Utilisation de Spring ResponseEntity pour manipuler la réponse HTTP

1. Introduction

En utilisant Spring, nous avons généralement de nombreuses façons d'atteindre le même objectif, y compris le réglage fin des réponses HTTP.

Dans ce court didacticiel, nous verrons comment définir le corps, l'état et les en-têtes d'une réponse HTTP à l'aide de ResponseEntity .

2. ResponseEntity

ResponseEntity représente l'ensemble de la réponse HTTP: code d'état, en-têtes et corps . En conséquence, nous pouvons l'utiliser pour configurer entièrement la réponse HTTP.

Si nous voulons l'utiliser, nous devons le renvoyer à partir du point final; Le printemps s'occupe du reste.

ResponseEntity est un type générique. Par conséquent, nous pouvons utiliser n'importe quel type comme corps de réponse:

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

Étant donné que nous spécifions l'état de la réponse par programme, nous pouvons retourner avec différents codes d'état pour différents scénarios:

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

De plus, nous pouvons définir des en-têtes HTTP:

@GetMapping("/customHeader") ResponseEntity customHeader() { HttpHeaders headers = new HttpHeaders(); headers.add("Custom-Header", "foo"); return new ResponseEntity( "Custom header set", headers, HttpStatus.OK); }

De plus, ResponseEntity fournit deux interfaces de générateur imbriquées : HeadersBuilder et sa sous- interface , BodyBuilder . Par conséquent, nous pouvons accéder à leurs capacités via les méthodes statiques de ResponseEntity .

Le cas le plus simple est une réponse avec un corps et un code de réponse HTTP 200:

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

Pour les codes d'état HTTP les plus populaires, nous obtenons des méthodes statiques:

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

De plus, nous pouvons utiliser les méthodes de statut BodyBuilder (statut HttpStatus) et de statut BodyBuilder (statut int) pour définir tout statut HTTP.

Enfin, avec ResponseEntity BodyBuilder.body (corps en T), nous pouvons définir le corps de la réponse HTTP:

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

Nous pouvons également définir des en-têtes personnalisés:

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

Puisque BodyBuilder.body () retourne un ResponseEntity au lieu de BodyBuilder, ce devrait être le dernier appel.

Notez qu'avec HeaderBuilder, nous ne pouvons définir aucune propriété du corps de la réponse.

En revenant ResponseEntity objet du contrôleur, nous pourrions obtenir une exception ou une erreur lors du traitement de la demande et que vous souhaitez renvoyer des informations liées à des erreurs de l'utilisateur représenté comme un autre type, disons E .

Spring 3.2 prend en charge un @ExceptionHandler global avec la nouvelle annotation @ControllerAdvice , qui gère ces types de scénarios. Pour plus de détails, reportez-vous à notre article existant ici.

Bien que ResponseEntity soit très puissant, nous ne devons pas en abuser. Dans les cas simples, il existe d'autres options qui répondent à nos besoins et qui aboutissent à un code beaucoup plus propre.

3. Alternatives

3.1. @ResponseBody

Dans les applications Spring MVC classiques, les points de terminaison renvoient généralement des pages HTML rendues. Parfois, nous n'avons besoin que de renvoyer les données réelles; par exemple, lorsque nous utilisons le point de terminaison avec AJAX.

Dans de tels cas, nous pouvons marquer la méthode du gestionnaire de requêtes avec @ResponseBody , et Spring traite la valeur de résultat de la méthode comme le corps de la réponse HTTP lui-même.

Pour plus d'informations, cet article est un bon point de départ.

3.2. @ResponseStatus

Lorsqu'un point de terminaison revient avec succès, Spring fournit une réponse HTTP 200 (OK). Si le point de terminaison lève une exception, Spring recherche un gestionnaire d'exceptions qui indique le statut HTTP à utiliser.

Nous pouvons marquer ces méthodes avec @ResponseStatus, et par conséquent, Spring retourne avec un statut HTTP personnalisé .

Pour plus d'exemples, veuillez consulter notre article sur les codes d'état personnalisés.

3.3. Manipuler la réponse directement

Spring nous permet également d'accéder directement à l'objet javax.servlet.http.HttpServletResponse ; il suffit de le déclarer comme argument de méthode:

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

Puisque Spring fournit des abstractions et des capacités supplémentaires au-dessus de l'implémentation sous-jacente, nous ne devons pas manipuler la réponse de cette façon .

4. Conclusion

Dans cet article, nous avons discuté de plusieurs façons de manipuler la réponse HTTP dans Spring, et examiné leurs avantages et leurs inconvénients.

Comme d'habitude, les exemples sont disponibles à l'adresse over sur GitHub.