Der Leitfaden zu RestTemplate

1. Übersicht

In diesem Tutorial werden wir die breite Palette von Vorgängen veranschaulichen, bei denen der Spring REST-Client - RestTemplate - verwendet werden kann und gut verwendet werden kann.

Für die API-Seite aller Beispiele führen wir von hier aus den RESTful-Service aus.

2. Verfallserklärung

Ab Spring Framework 5 führte Spring neben dem WebFlux-Stack einen neuen HTTP-Client namens WebClient ein .

WebClient ist ein moderner, alternativer HTTP-Client zu RestTemplate . Es bietet nicht nur eine herkömmliche synchrone API, sondern unterstützt auch einen effizienten nicht blockierenden und asynchronen Ansatz.

Wenn wir jedoch neue Anwendungen entwickeln oder eine alte migrieren, ist es eine gute Idee, WebClient zu verwenden . In Zukunft wird RestTemplate in zukünftigen Versionen nicht mehr unterstützt.

3. Verwenden Sie GET, um Ressourcen abzurufen

3.1. Holen Sie sich Plain JSON

Fangen wir einfach und reden über GET - Anfragen, mit einem schnellen Beispiel mit der getForEntity () API :

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

Beachten Sie, dass wir vollen Zugriff auf die HTTP-Antwort haben , sodass wir beispielsweise den Statuscode überprüfen können, um sicherzustellen, dass der Vorgang erfolgreich war, oder mit dem tatsächlichen Hauptteil der Antwort arbeiten können:

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

Wir arbeiten hier mit dem Antworttext als Standardzeichenfolge und verwenden Jackson (und die von Jackson bereitgestellte JSON-Knotenstruktur), um einige Details zu überprüfen.

3.2. POJO anstelle von JSON abrufen

Wir können die Antwort auch direkt einem Ressourcen-DTO zuordnen:

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

4. Verwenden Sie HEAD, um Header abzurufen

Lassen Sie uns nun einen kurzen Blick auf die Verwendung von HEAD werfen, bevor wir zu den allgemeineren Methoden übergehen.

Wir werden hier die headForHeaders () API verwenden:

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

5. Verwenden Sie POST, um eine Ressource zu erstellen

Um eine neue Ressource in der API zu erstellen, können wir die APIs postForLocation () , postForObject () oder postForEntity () gut nutzen .

Der erste gibt den URI der neu erstellten Ressource zurück, während der zweite die Ressource selbst zurückgibt.

5.1. Die postForObject () API

RestTemplate restTemplate = new RestTemplate(); HttpEntity 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

Schauen wir uns auch die Operation an, bei der anstelle der vollständigen Ressource nur der Speicherort dieser neu erstellten Ressource zurückgegeben wird:

HttpEntity 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 ein POST mit der allgemeineren Austausch- API durchgeführt wird:

RestTemplate restTemplate = new RestTemplate(); HttpEntity request = new HttpEntity(new Foo("bar")); ResponseEntity 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. Formulardaten senden

Als nächstes schauen wir uns an, wie Sie ein Formular mit der POST-Methode senden.

Zuerst müssen wir den Content-Type- Header auf application / x-www-form-urlencoded setzen.

Dadurch wird sichergestellt, dass eine große Abfragezeichenfolge an den Server gesendet werden kann, die 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 einschließen :

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

Als Nächstes erstellen wir die Anforderung mithilfe einer HttpEntity- Instanz :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

Schließlich können wir eine Verbindung zum REST-Service herstellen, indem wir restTemplate.postForEntity () auf dem Endpunkt: / foos / form aufrufen

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

6. Verwenden Sie OPTIONEN, um zulässige Vorgänge abzurufen

Als Nächstes werden wir einen kurzen Blick auf die Verwendung einer OPTIONS-Anforderung werfen und die zulässigen Operationen für einen bestimmten URI mithilfe dieser Art von Anforderung untersuchen. Die API lautet optionsForAllow :

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

7. Verwenden Sie PUT, um eine Ressource zu aktualisieren

Next, we'll start looking at PUT and more specifically the exchange() API for this operation, since the template.put API is pretty straightforward.

7.1. Simple PUT With exchange()

We'll start with a simple PUT operation against the API — and keep in mind that the operation isn't returning a body back to the client:

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

7.2. PUT With exchange() and a Request Callback

Next, we're going to be using a request callback to issue a PUT.

Let's make sure we prepare the callback, where we can set all the headers we need as well as a request body:

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

Next, we create the Resource with a POST request:

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

And then we update the Resource:

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

8. Use DELETE to Remove a Resource

Um eine vorhandene Ressource zu entfernen, verwenden wir schnell die delete () -API:

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

9. Konfigurieren Sie das Zeitlimit

Wir können RestTemplate so konfigurieren, dass eine Zeitüberschreitung auftritt , 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 Konfigurationsoptionen 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); }

10. Schlussfolgerung

In diesem Artikel gingen wir die wichtigsten HTTP-Verben durch und verwendeten RestTemplate, um Anforderungen mit all diesen zu orchestrieren.

Wenn Sie sich mit der Authentifizierung mit der Vorlage befassen möchten, lesen Sie unseren Artikel über die grundlegende Authentifizierung mit RestTemplate.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie auf GitHub.