Übersicht
In diesem Tutorial werden wir die breite Palette von Operationen illustrieren, bei denen der Spring REST-Client – RestTemplate – eingesetzt werden kann, und zwar gut eingesetzt.
Für die API-Seite aller Beispiele werden wir den RESTful-Service von hier aus ausführen.
Weiterlesen:
Basic Authentication with the RestTemplate
RestTemplate mit Digest-Authentifizierung
Exploring the Spring Boot TestRestTemplate
Abkündigungshinweis
Mit Spring Framework 5 hat Spring neben dem WebFlux-Stack einen neuen HTTP-Client namens WebClient eingeführt.
WebClient ist ein moderner, alternativer HTTP-Client zum RestTemplate. Er bietet nicht nur eine traditionelle synchrone API, sondern unterstützt auch einen effizienten nicht-blockierenden und asynchronen Ansatz.
Das heißt, wenn wir neue Anwendungen entwickeln oder eine alte migrieren, ist es eine gute Idee, WebClient zu verwenden. In Zukunft wird RestTemplate in zukünftigen Versionen veraltet sein.
Verwenden Sie GET, um Ressourcen abzurufen
3.1. Einfaches JSON abrufen
Lassen Sie uns einfach beginnen und über GET-Anfragen sprechen, mit einem schnellen Beispiel unter Verwendung der getForEntity()-API:
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));
Beachten Sie, dass wir vollen Zugriff auf die HTTP-Antwort haben, so dass wir Dinge tun können, wie den Statuscode zu überprüfen, um sicherzustellen, dass die Operation erfolgreich war oder mit dem tatsächlichen Körper der Antwort arbeiten:
ObjectMapper mapper = new ObjectMapper();JsonNode root = mapper.readTree(response.getBody());JsonNode name = root.path("name");assertThat(name.asText(), notNullValue());
Wir arbeiten hier mit dem Antwortkörper als Standard-String und verwenden Jackson (und die JSON-Knotenstruktur, die Jackson bereitstellt), um einige Details zu überprüfen.
3.2. POJO statt JSON abrufen
Wir können die Antwort auch direkt auf ein Ressourcen-DTO mappen:
public class Foo implements Serializable { private long id; private String name; // standard getters and setters}
Jetzt können wir einfach die getForObject-API in der Vorlage verwenden:
Foo foo = restTemplate .getForObject(fooResourceUrl + "/1", Foo.class);assertThat(foo.getName(), notNullValue());assertThat(foo.getId(), is(1L));
Use HEAD to Retrieve Headers
Lassen Sie uns nun einen kurzen Blick auf die Verwendung von HEAD werfen, bevor wir zu den häufigeren Methoden übergehen.
Wir werden hier die headForHeaders() API verwenden:
HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl);assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));
Verwenden Sie POST, um eine Ressource zu erstellen
Um eine neue Ressource in der API zu erstellen, können wir die postForLocation(), postForObject() oder postForEntity() APIs gut verwenden.
Die erste gibt den URI der neu erstellten Ressource zurück, während die zweite die Ressource selbst zurückgibt.
5.1. Die postForObject() API
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. Die postForLocation() API
Werfen wir einen Blick auf die Operation, die statt der vollständigen Ressource nur den Ort der neu erstellten Ressource zurückgibt:
HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));URI location = restTemplate .postForLocation(fooResourceUrl, request);assertThat(location, notNullValue());
5.3. Die exchange()-API
Lassen Sie uns einen Blick darauf werfen, wie man ein POST mit der allgemeineren exchange-API durchführt:
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. Absenden von Formulardaten
Als nächstes schauen wir uns an, wie man ein Formular mit der POST-Methode absendet.
Zuerst müssen wir den Content-Type-Header auf application/x-www-form-urlencoded setzen.
Damit wird sichergestellt, dass ein großer Query-String an den Server gesendet werden kann, der durch & getrennte Name/Wert-Paare enthält:
HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
Wir können die Formularvariablen in eine LinkedMultiValueMap einpacken:
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();map.add("id", "1");
Als Nächstes bauen wir den Request mit einer HttpEntity-Instanz auf:
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
Schließlich können wir uns mit dem REST-Dienst verbinden, indem wir restTemplate.postForEntity() auf dem Endpunkt: /foos/form
ResponseEntity<String> response = restTemplate.postForEntity( fooResourceUrl+"/form", request , String.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
Verwenden Sie OPTIONS, um erlaubte Operationen abzurufen
Als Nächstes werfen wir einen kurzen Blick auf die Verwendung einer OPTIONS-Anfrage und erkunden die erlaubten Operationen für einen bestimmten URI mit dieser Art von Anfrage; die API heißt optionsForAllow:
Set<HttpMethod> optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);HttpMethod supportedMethods = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));
Verwenden Sie PUT, um eine Ressource zu aktualisieren
Als Nächstes schauen wir uns PUT und genauer gesagt die exchange()-API für diese Operation an, da die template.put-API ziemlich unkompliziert ist.
7.1. Einfaches PUT mit exchange()
Wir beginnen mit einer einfachen PUT-Operation gegen die API – und denken Sie daran, dass die Operation keinen Body an den Client zurückgibt:
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 mit exchange() und einem Request Callback
Als Nächstes werden wir einen Request Callback verwenden, um ein PUT auszuführen.
Lassen Sie uns den Callback vorbereiten, in dem wir alle benötigten Header sowie einen Request-Body setzen können:
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()); };}
Nächstens erzeugen wir die Ressource mit einer POST-Anfrage:
ResponseEntity<Foo> response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
Und dann aktualisieren wir die 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);
DELETE verwenden, um eine Ressource zu entfernen
Um eine vorhandene Ressource zu entfernen, machen wir schnellen Gebrauch von der delete() API:
String entityUrl = fooResourceUrl + "/" + existingResource.getId();restTemplate.delete(entityUrl);
Timeout konfigurieren
Wir können RestTemplate für einen Timeout konfigurieren, indem wir einfach ClientHttpRequestFactory verwenden:
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory;}
Und wir können HttpClient für weitere Konfigurationsmöglichkeiten verwenden:
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);}
Abschluss
In diesem Artikel sind wir die wichtigsten HTTP-Verben durchgegangen und haben RestTemplate verwendet, um Anfragen mit all diesen zu orchestrieren.
Wenn Sie sich für die Authentifizierung mit dem Template interessieren, lesen Sie unseren Artikel über Basic Auth mit RestTemplate.
Die Implementierung all dieser Beispiele und Codeschnipsel finden Sie drüben auf GitHub.
Starten Sie mit Spring 5 und Spring Boot 2, durch den Learn Spring Kurs:
>> CHECK OUT THE COURSE