Utilisation de Spring ResponseEntity pour manipuler la réponse HTTP

Utilisation de Spring ResponseEntity pour manipuler la réponse HTTP

1. introduction

En utilisant Spring, nous avons généralement plusieurs moyens pour atteindre le même objectif, notamment en affinant les 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 deResponseEntity.

Lectures complémentaires:

Obtention et vérification des données de réponse avec REST-assuré

Découvrez comment utiliser REST-assure pour valider et extraire la réponse d'un noeud final REST.

Read more

Utilisation de Spring @ResponseStatus pour définir le code d'état HTTP

Examinez l'annotation @ResponseStatus et son utilisation pour définir le code d'état de la réponse.

Read more

2. ResponseEntity

ResponseEntityrepresents the whole HTTP response: status code, headers, and body. De ce fait, nous pouvons l’utiliser pour configurer complètement la réponse HTTP.

Si nous voulons l'utiliser, nous devons le renvoyer depuis le noeud final; Le printemps s'occupe du reste.

ResponseEntity est un type générique. En conséquence, nous pouvons utiliser n'importe quel type en tant que corps de réponse:

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

Comme nous spécifions l'état de la réponse par programme, nous pouvons renvoyer 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,ResponseEntityprovides two nested builder interfaces:HeadersBuilder et sa sous-interface,BodyBuilder. Par conséquent, nous pouvons accéder à leurs capacités via les méthodes statiques deResponseEntity.

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 de statut 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éthodesBodyBuilder status(HttpStatus status) etBodyBuilder status(int status) pour définir n'importe quel état HTTP.

Enfin, avecResponseEntity<T> BodyBuilder.body(T body), 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");
}

Par conséquent,BodyBuilder.body() renvoie unResponseEntity au lieu deBodyBuilder,, ce devrait être le dernier appel.

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

En retournant l'objetResponseEntity<T> du contrôleur, nous pourrions obtenir une exception ou une erreur lors du traitement de la requête et souhaiterionsreturn error-related information to the user represented as some other type let’s say E.

Spring 3.2 prend en charge un@ExceptionHandler with the new @ControllerAdvice annotationglobal qui gère ces types de scénarios. Pour plus de détails, reportez-vous à notre article existanthere.

While ResponseEntity is very powerful, we shouldn’t overuse it. Dans les cas simples, il existe d'autres options qui satisfont nos besoins et qui aboutissent à un code beaucoup plus propre.

3. Des alternatives

3.1. @ResponseBody

Dans les applications Spring classiques de Spring MVC, les points de terminaison renvoient généralement les pages HTML rendues. Parfois, il suffit de renvoyer les données réelles, par exemple, lorsque nous utilisons le noeud final avec AJAX.

Dans de tels cas, nous pouvons marquer la méthode du gestionnaire de requêtes avec@ResponseBody etSpring treats the result value of the method as the HTTP response body lui-même.

Pour plus d'informations,this article is a good place to start.

3.2. @ResponseStatus

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

Nous pouvons marquer ces méthodes avec @ResponseStatus. Par conséquent Springreturns with a custom HTTP status.

Pour plus d'exemples, veuillez consulter notre article surcustom status codes.

3.3. Manipuler la réponse directement

Spring nous permet également d'accéder directement à l'objetjavax.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,we shouldn’t manipulate the response this way.

4. Conclusion

Dans cet article, nous avons vu plusieurs manières, avec leurs avantages et inconvénients, de manipuler la réponse HTTP au printemps.

Comme d'habitude, les exemples sont disponiblesover on GitHub.