RestTemplate Post Request avec JSON

Haut REST

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Introduction

Dans ce tutoriel rapide, nous illustrons comment utiliser le RestTemplate de Spring pour effectuer des requêtes POST envoyant du contenu JSON.

2. Configuration de l'exemple

Commençons par ajouter une classe de modèle Person simple pour représenter les données à publier:

public class Person { private Integer id; private String name; // standard constructor, getters, setters }

Pour travailler avec des objets Person , nous ajouterons une interface PersonService et une implémentation avec deux méthodes:

public interface PersonService { public Person saveUpdatePerson(Person person); public Person findPersonById(Integer id); }

L'implémentation de ces méthodes renverra simplement un objet. Nous utilisons ici une implémentation factice de cette couche afin de pouvoir nous concentrer sur la couche Web.

3. Configuration de l'API REST

Définissons une API REST simple pour notre classe Person :

@PostMapping( value = "/createPerson", consumes = "application/json", produces = "application/json") public Person createPerson(@RequestBody Person person) { return personService.saveUpdatePerson(person); } @PostMapping( value = "/updatePerson", consumes = "application/json", produces = "application/json") public Person updatePerson(@RequestBody Person person, HttpServletResponse response) { response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath() .path("/findPerson/" + person.getId()).toUriString()); return personService.saveUpdatePerson(person); }

N'oubliez pas que nous voulons publier les données au format JSON. Pour cela, nous avons ajouté le consume attribut dans la @PostMapping annotation avec la valeur de « application / json » pour les deux méthodes.

De même, nous définissons l' attribut produit sur «application / json» pour indiquer à Spring que nous voulons que le corps de la réponse soit au format JSON.

Nous avons annoté le paramètre person avec l' annotation @RequestBody pour les deux méthodes. Cela indiquera à Spring que l' objet personne sera lié au corps de la requête HTTP .

Enfin, les deux méthodes renvoient un objet Person qui sera lié au corps de la réponse. Notons que nous annotons notre classe API avec @RestController pour annoter toutes les méthodes API avec une annotation @ResponseBody masquée .

4. Utilisation de RestTemplate

Nous pouvons maintenant écrire quelques tests unitaires pour tester notre API REST Person . Ici, nous allons essayer d'envoyer des requêtes POST à ​​l' API Person en utilisant les méthodes POST fournies par RestTemplate : postForObject , postForEntity et postForLocation .

Avant de commencer à implémenter nos tests unitaires, définissons une méthode de configuration pour initialiser les objets que nous utiliserons dans toutes nos méthodes de test unitaires:

@BeforeClass public static void runBeforeAllTestMethods() { createPersonUrl = "//localhost:8082/spring-rest/createPerson"; updatePersonUrl = "//localhost:8082/spring-rest/updatePerson"; restTemplate = new RestTemplate(); headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); personJsonObject = new JSONObject(); personJsonObject.put("id", 1); personJsonObject.put("name", "John"); }

Outre cette méthode de configuration, notez que nous ferons référence au mappeur suivant pour convertir la chaîne JSON en un objet JSONNode dans nos tests unitaires:

private final ObjectMapper objectMapper = new ObjectMapper();

Comme mentionné précédemment, nous souhaitons publier les données au format JSON. Pour ce faire, nous ajouterons un en - tête Content-Type à notre requête avec le type de média APPLICATION_JSON .

La classe HttpHeaders de Spring fournit différentes méthodes pour accéder aux en-têtes. Ici, nous définissons l'en - tête Content-Type sur application / json en appelant la méthode setContentType . Nous attacherons l' objet headers à nos requêtes.

4.1. Publication de JSON avec postForObject

RestTemplate de postForObject méthode crée une nouvelle ressource en affichant un objet au modèle URI donné. Il renvoie le résultat automatiquement converti dans le type spécifié dans le paramètre responseType .

Disons que nous voulons faire une requête POST à ​​notre API Person pour créer un nouvel objet Person et renvoyer cet objet nouvellement créé dans la réponse.

Tout d'abord, nous allons créer l' objet de requête de type HttpEntity basé sur le personJsonObject et les en-têtes contenant le Content-Type . Cela permet à la méthode postForObject d'envoyer un corps de requête JSON:

@Test public void givenDataIsJson_whenDataIsPostedByPostForObject_thenResponseBodyIsNotNull() throws IOException { HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); String personResultAsJsonStr = restTemplate.postForObject(createPersonUrl, request, String.class); JsonNode root = objectMapper.readTree(personResultAsJsonStr); assertNotNull(personResultAsJsonStr); assertNotNull(root); assertNotNull(root.path("name").asText()); }

La méthode postForObject () renvoie le corps de la réponse sous la forme d'un type String .

Nous pouvons également renvoyer la réponse en tant qu'objet Person en définissant le paramètre responseType :

Person person = restTemplate.postForObject(createPersonUrl, request, Person.class); assertNotNull(person); assertNotNull(person.getName());

En fait, notre méthode de gestionnaire de requêtes correspondant à l' URI createPersonUrl produit le corps de la réponse au format JSON.

Mais ce n'est pas une limitation pour nous - postForObject est capable de convertir automatiquement le corps de la réponse dans le type Java demandé (par exemple String , Person ) spécifié dans le paramètre responseType .

4.2. Publication de JSON avec postForEntity

Par rapport à postForObject () , postForEntity () renvoie la réponse sous la forme d'un objet ResponseEntity . À part cela, les deux méthodes font le même travail.

Disons que nous voulons faire une requête POST à ​​notre API Person pour créer un nouvel objet Person et renvoyer la réponse en tant que ResponseEntity .

Nous pouvons utiliser la méthode postForEntity pour implémenter ceci:

@Test public void givenDataIsJson_whenDataIsPostedByPostForEntity_thenResponseBodyIsNotNull() throws IOException { HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); ResponseEntity responseEntityStr = restTemplate. postForEntity(createPersonUrl, request, String.class); JsonNode root = objectMapper.readTree(responseEntityStr.getBody()); assertNotNull(responseEntityStr.getBody()); assertNotNull(root.path("name").asText()); }

Semblable à postForObject , postForEntity a le paramètre responseType pour convertir le corps de la réponse en type Java demandé.

Ici, nous avons pu renvoyer le corps de la réponse en tant que ResponseEntity .

Nous pouvons également renvoyer la réponse en tant qu'objet ResponseEntity en définissant le paramètre responseType sur Person.class :

ResponseEntity responseEntityPerson = restTemplate. postForEntity(createPersonUrl, request, Person.class); assertNotNull(responseEntityPerson.getBody()); assertNotNull(responseEntityPerson.getBody().getName());

4.3. Publication de JSON avec postForLocation

Semblable aux méthodes postForObject et postForEntity , postForLocation crée également une nouvelle ressource en publiant l'objet donné dans l'URI donné. La seule différence est qu'il renvoie la valeur de l'en- tête Location .

N'oubliez pas que nous avons déjà vu comment définir l'en- tête Location d'une réponse dans notre méthode API REST updatePerson ci-dessus:

response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath() .path("/findPerson/" + person.getId()).toUriString());

Imaginons maintenant que nous souhaitons renvoyer l'en- tête Location de la réponse après la mise à jour de l' objet personne que nous avons publié.

Nous pouvons l'implémenter en utilisant la méthode postForLocation :

@Test public void givenDataIsJson_whenDataIsPostedByPostForLocation_thenResponseBodyIsTheLocationHeader() throws JsonProcessingException { HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); URI locationHeader = restTemplate.postForLocation(updatePersonUrl, request); assertNotNull(locationHeader); }

5. Conclusion

Dans cet article, nous avons exploré comment utiliser RestTemplate pour effectuer une requête POST avec JSON.

Comme toujours, tous les exemples et extraits de code peuvent être trouvés sur GitHub.

REST bas

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS