Articles

Le guide du RestTemplate

Posted on

Overview

Dans ce tutoriel, nous allons illustrer le large éventail d’opérations où le client REST de Spring – RestTemplate – peut être utilisé, et bien utilisé.

Pour le côté API de tous les exemples, nous allons exécuter le service RESTful à partir d’ici.

Lectures complémentaires:

Authentification de base avec le RestTemplate

Comment faire une authentification de base avec le Spring RestTemplate.
Lire la suite →

RestTemplate avec authentification Digest

Comment configurer l’authentification Digest pour le Spring RestTemplate en utilisant HttpClient 4.
Lire la suite →

Explorer le TestRestTemplate de Spring Boot

Apprenez à utiliser le nouveau TestRestTemplate de Spring Boot pour tester une API simple.
Lire la suite →

Avis de dépréciation

A compter de Spring Framework 5, parallèlement à la pile WebFlux, Spring a introduit un nouveau client HTTP appelé WebClient.

WebClient est un client HTTP moderne, alternatif à RestTemplate. Non seulement il fournit une API synchrone traditionnelle, mais il prend également en charge une approche non bloquante et asynchrone efficace.

Cela dit, si nous développons de nouvelles applications ou si nous migrons une ancienne application, c’est une bonne idée d’utiliser WebClient. En allant de l’avant, RestTemplate sera déprécié dans les futures versions.

Utiliser GET pour récupérer des ressources

3.1. Obtenir du JSON pur

Débutons simplement et parlons des requêtes GET, avec un exemple rapide utilisant l’API getForEntity():

RestTemplate restTemplate = new RestTemplate();String fooResourceUrl = "http://localhost:8080/spring-rest/foos";ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class);assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));

Notez que nous avons un accès complet à la réponse HTTP, de sorte que nous pouvons faire des choses comme vérifier le code d’état pour s’assurer que l’opération a réussi ou travailler avec le corps réel de la réponse :

ObjectMapper mapper = new ObjectMapper();JsonNode root = mapper.readTree(response.getBody());JsonNode name = root.path("name");assertThat(name.asText(), notNullValue());

Nous travaillons avec le corps de la réponse comme une chaîne standard ici et utilisons Jackson (et la structure de nœuds JSON que Jackson fournit) pour vérifier certains détails.

3.2. Récupération de POJO au lieu de JSON

Nous pouvons également mapper la réponse directement à un DTO de ressource :

public class Foo implements Serializable { private long id; private String name; // standard getters and setters}

Maintenant, nous pouvons simplement utiliser l’API getForObject dans le modèle :

Foo foo = restTemplate .getForObject(fooResourceUrl + "/1", Foo.class);assertThat(foo.getName(), notNullValue());assertThat(foo.getId(), is(1L));

Utiliser HEAD pour récupérer les en-têtes

Voyons maintenant rapidement comment utiliser HEAD avant de passer aux méthodes plus courantes.

Nous allons utiliser ici l’API headForHeaders() :

HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl);assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));

Utiliser POST pour créer une ressource

Pour créer une nouvelle ressource dans l’API, nous pouvons faire bon usage des API postForLocation(), postForObject() ou postForEntity().

La première renvoie l’URI de la ressource nouvellement créée, tandis que la seconde renvoie la ressource elle-même.

5.1. L’API postForObject()

RestTemplate restTemplate = new RestTemplate();HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class);assertThat(foo, notNullValue());assertThat(foo.getName(), is("bar"));

5.2. L’API postForLocation()

Similairement, jetons un coup d’œil à l’opération qui, au lieu de renvoyer la ressource complète, renvoie juste l’emplacement de cette ressource nouvellement créée:

HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));URI location = restTemplate .postForLocation(fooResourceUrl, request);assertThat(location, notNullValue());

5.3. L’API exchange()

Voyons comment faire un POST avec l’API exchange plus générique:

RestTemplate restTemplate = new RestTemplate();HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));ResponseEntity<Foo> response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); Foo foo = response.getBody(); assertThat(foo, notNullValue());assertThat(foo.getName(), is("bar"));

5.4. Soumettre les données du formulaire

Voyons ensuite comment soumettre un formulaire à l’aide de la méthode POST.

D’abord, nous devons définir l’en-tête Content-Type sur application/x-www-form-urlencoded.

Cela permet de s’assurer qu’une grande chaîne de requête peut être envoyée au serveur, contenant des couples nom/valeur séparés par &:

HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

Nous pouvons envelopper les variables du formulaire dans un LinkedMultiValueMap :

MultiValueMap<String, String> map= new LinkedMultiValueMap<>();map.add("id", "1");

Puis, nous construisons la requête en utilisant une instance HttpEntity:

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

Enfin, nous pouvons nous connecter au service REST en appelant restTemplate.postForEntity() sur le point de terminaison : /foos/form

ResponseEntity<String> response = restTemplate.postForEntity( fooResourceUrl+"/form", request , String.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

Utiliser OPTIONS pour obtenir les opérations autorisées

A la suite, nous allons jeter un coup d’œil rapide à l’utilisation d’une requête OPTIONS et explorer les opérations autorisées sur une URI spécifique en utilisant ce type de requête ; l’API est optionsForAllow :

Set<HttpMethod> optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);HttpMethod supportedMethods = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));

Utiliser PUT pour mettre à jour une ressource

Après, nous allons commencer à examiner PUT et plus précisément l’API exchange() pour cette opération, puisque le modèle.put API est assez simple.

7.1. PUT simple avec exchange()

Nous allons commencer par une opération PUT simple contre l’API – et gardez à l’esprit que l’opération ne renvoie pas de corps au client :

Foo updatedInstance = new Foo("newName");updatedInstance.setId(createResponse.getBody().getId());String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId();HttpEntity<Foo> requestUpdate = new HttpEntity<>(updatedInstance, headers);template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);

7.2. PUT avec exchange() et une callback de requête

A la suite, nous allons utiliser une callback de requête pour émettre un PUT.

Vérifions que nous préparons le callback, où nous pouvons définir tous les en-têtes dont nous avons besoin ainsi qu’un corps de requête :

RequestCallback requestCallback(final Foo updatedInstance) { return clientHttpRequest -> { ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(clientHttpRequest.getBody(), updatedInstance); clientHttpRequest.getHeaders().add( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); clientHttpRequest.getHeaders().add( HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); };}

Puis, nous créons la ressource avec une requête POST :

ResponseEntity<Foo> response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

Et ensuite, nous mettons à jour la ressource :

Foo updatedInstance = new Foo("newName");updatedInstance.setId(response.getBody().getId());String resourceUrl =fooResourceUrl + '/' + response.getBody().getId();restTemplate.execute( resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null);

Utiliser DELETE pour supprimer une ressource

Pour supprimer une ressource existante, nous allons utiliser rapidement l’API delete() :

String entityUrl = fooResourceUrl + "/" + existingResource.getId();restTemplate.delete(entityUrl);

Configurer le délai d’attente

Nous pouvons configurer RestTemplate pour qu’il dépasse le délai d’attente en utilisant simplement ClientHttpRequestFactory:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory;}

Et nous pouvons utiliser HttpClient pour d’autres options de configuration :

private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; RequestConfig config = RequestConfig.custom() .setConnectTimeout(timeout) .setConnectionRequestTimeout(timeout) .setSocketTimeout(timeout) .build(); CloseableHttpClient client = HttpClientBuilder .create() .setDefaultRequestConfig(config) .build(); return new HttpComponentsClientHttpRequestFactory(client);}

Conclusion

Dans cet article, nous avons parcouru les principaux verbes HTTP, en utilisant RestTemplate pour orchestrer des requêtes utilisant tous ceux-ci.

Si vous voulez creuser la façon de faire de l’authentification avec le modèle, consultez notre article sur Basic Auth avec RestTemplate.

L’implémentation de tous ces exemples et extraits de code se trouve sur GitHub.

Démarrez avec Spring 5 et Spring Boot 2, grâce au cours Learn Spring:

>> VÉRIFIER LE COURS

.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *