RestTemplate Post Request mit JSON

REST Top

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Einleitung

In diesem kurzen Tutorial zeigen wir, wie Sie mit Spring's RestTemplate POST-Anforderungen senden, die JSON-Inhalte senden.

2. Einrichten des Beispiels

Beginnen wir mit dem Hinzufügen einer einfachen Personenmodellklasse , um die zu postenden Daten darzustellen:

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

Um mit Personenobjekten zu arbeiten , fügen wir eine PersonService- Schnittstelle und -Implementierung mit zwei Methoden hinzu:

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

Die Implementierung dieser Methoden gibt einfach ein Objekt zurück. Wir verwenden hier eine Dummy-Implementierung dieser Ebene, damit wir uns auf die Webebene konzentrieren können.

3. REST-API-Setup

Definieren wir eine einfache REST-API für unsere Personenklasse :

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

Denken Sie daran, wir möchten die Daten im JSON-Format veröffentlichen. Um das, haben wir die Verbraucht im Attribut @PostMapping Annotation mit dem Wert von „application / json“ für beide Methoden.

In ähnlicher Weise haben wir das produziert Attribut „application / json“ Spring sagen , dass wir die Antworttext im JSON - Format möchten.

Wir haben den Parameter person mit der Annotation @RequestBody für beide Methoden versehen. Dadurch wird Spring mitgeteilt, dass das Personenobjekt an den Hauptteil der HTTP- Anforderung gebunden wird .

Schließlich geben beide Methoden ein Personenobjekt zurück , das an den Antworttext gebunden wird. Beachten Sie, dass wir unsere API-Klasse mit @RestController versehen, um alle API-Methoden mit einer versteckten @ ResponseBody- Annotation zu versehen.

4. Verwenden von RestTemplate

Jetzt können wir einige Unit-Tests schreiben, um unsere Person REST-API zu testen . Hier versuchen wir, POST-Anforderungen mithilfe der von RestTemplate bereitgestellten POST-Methoden an die Personen- API zu senden : postForObject , postForEntity und postForLocation .

Bevor wir mit der Implementierung unserer Komponententests beginnen, definieren wir eine Setup-Methode, um die Objekte zu initialisieren, die wir in allen unseren Komponententestmethoden verwenden:

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

Beachten Sie, dass wir uns neben dieser Setup-Methode auf den folgenden Mapper beziehen, um den JSON-String in unseren Komponententests in ein JSONNode- Objekt zu konvertieren :

private final ObjectMapper objectMapper = new ObjectMapper();

Wie bereits erwähnt, möchten wir die Daten im JSON-Format veröffentlichen. Um dies zu erreichen, fügen wir unserer Anfrage einen Content-Type- Header mit dem Medientyp APPLICATION_JSON hinzu .

Die HttpHeaders- Klasse von Spring bietet verschiedene Methoden für den Zugriff auf die Header. Hier setzen wir den Content-Type- Header durch Aufrufen der setContentType- Methode auf application / json . Wir werden das Header- Objekt an unsere Anfragen anhängen .

4.1. JSON mit postForObject posten

Die postForObject - Methode von RestTemplate erstellt eine neue Ressource, indem ein Objekt an die angegebene URI-Vorlage gesendet wird. Das Ergebnis wird automatisch in den im Parameter responseType angegebenen Typ konvertiert zurückgegeben .

Angenommen, wir möchten eine POST-Anforderung an unsere Personen- API senden, um ein neues Personenobjekt zu erstellen und dieses neu erstellte Objekt in der Antwort zurückzugeben.

Zuerst erstellen wir das Anforderungsobjekt vom Typ HttpEntity basierend auf dem personJsonObject und den Headern, die den Inhaltstyp enthalten . Dadurch kann die postForObject- Methode einen JSON-Anforderungshauptteil senden:

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

Die postForObject () -Methode gibt den Antworttext als String- Typ zurück.

Wir können die Antwort auch als Personenobjekt zurückgeben , indem wir den Parameter responseType festlegen:

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

Tatsächlich erzeugt unsere Request-Handler-Methode, die mit dem URI createPersonUrl übereinstimmt, den Antworttext im JSON-Format.

Dies ist jedoch keine Einschränkung für uns - postForObject kann den Antworttext automatisch in den angeforderten Java-Typ (z. B. String , Person ) konvertieren, der im Parameter responseType angegeben ist.

4.2. JSON mit postForEntity veröffentlichen

Im Vergleich zu postForObject () gibt postForEntity () die Antwort als ResponseEntity- Objekt zurück. Davon abgesehen erledigen beide Methoden den gleichen Job.

Angenommen, wir möchten eine POST-Anforderung an unsere Personen- API senden, um ein neues Personenobjekt zu erstellen und die Antwort als ResponseEntity zurückzugeben .

Wir können die postForEntity- Methode verwenden, um dies zu implementieren:

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

Ähnlich wie beim postForObject verfügt postForEntity über den Parameter responseType , um den Antworttext in den angeforderten Java-Typ zu konvertieren.

Hier konnten wir den Antworttext als ResponseEntity zurückgeben .

We can also return the response as a ResponseEntity object by setting the responseType parameter to Person.class:

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

4.3. Posting JSON With postForLocation

Similar to the postForObject and postForEntity methods, postForLocation also creates a new resource by posting the given object to the given URI. The only difference is that it returns the value of the Location header.

Remember, we already saw how to set the Location header of a response in our updatePerson REST API method above:

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

Stellen wir uns nun vor, wir möchten den Location- Header der Antwort zurückgeben, nachdem wir das von uns veröffentlichte Personenobjekt aktualisiert haben.

Wir können dies mithilfe der postForLocation- Methode implementieren :

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

5. Schlussfolgerung

In diesem Artikel haben wir untersucht, wie Sie mit RestTemplate eine POST-Anforderung mit JSON erstellen .

Wie immer finden Sie alle Beispiele und Codefragmente auf GitHub.

REST unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs