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
RestTemplate avec authentification Digest
Explorer le TestRestTemplate de Spring Boot
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
.