Ghidul pentru RestTemplate

1. Prezentare generală

În acest tutorial, vom ilustra gama largă de operații în care Spring REST Client - RestTemplate - poate fi utilizat și utilizat bine.

Pentru partea API a tuturor exemplelor, vom rula serviciul RESTful de aici.

2. Notificare privind deprecierea

Începând cu Spring Framework 5, alături de stiva WebFlux, Spring a introdus un nou client HTTP numit WebClient .

WebClient este un client HTTP modern, alternativ la RestTemplate . Nu numai că oferă un API sincron tradițional, dar acceptă și o abordare asincronă și non-blocare eficientă.

Acestea fiind spuse, dacă dezvoltăm aplicații noi sau migrăm una veche, este o idee bună să utilizați WebClient . Înainte, RestTemplate va fi depreciat în versiunile viitoare.

3. Utilizați GET pentru a prelua resurse

3.1. Obțineți JSON simplu

Să începem simplu și să vorbim despre solicitările GET, cu un exemplu rapid folosind API-ul getForEntity () :

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

Observați că avem acces deplin la răspunsul HTTP , deci putem face lucruri precum verificarea codului de stare pentru a ne asigura că operațiunea a avut succes sau pentru a lucra cu corpul real al răspunsului:

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

Lucrăm cu corpul de răspuns ca un șir standard aici și folosim Jackson (și structura nodului JSON pe care Jackson o oferă) pentru a verifica unele detalii.

3.2. Preluarea POJO în loc de JSON

De asemenea, putem mapa răspunsul direct la un resurs DTO:

public class Foo implements Serializable { private long id; private String name; // standard getters and setters }

Acum putem folosi pur și simplu getForObject API în șablon:

Foo foo = restTemplate .getForObject(fooResourceUrl + "/1", Foo.class); assertThat(foo.getName(), notNullValue()); assertThat(foo.getId(), is(1L));

4. Folosiți HEAD pentru a prelua anteturi

Să aruncăm o privire rapidă la utilizarea HEAD înainte de a trece la metodele mai comune.

Vom folosi aici headForHeaders () API:

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

5. Utilizați POST pentru a crea o resursă

Pentru a crea o nouă resursă în API, putem folosi bine API-urile postForLocation () , postForObject () sau postForEntity () .

Primul returnează URI-ul resursei nou create, în timp ce al doilea returnează resursa în sine.

5.1. 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. PostForLocation () API

În mod similar, să aruncăm o privire asupra operației care, în loc să returneze resursa completă, returnează doar locația resursei nou create:

HttpEntity request = new HttpEntity(new Foo("bar")); URI location = restTemplate .postForLocation(fooResourceUrl, request); assertThat(location, notNullValue());

5.3. Schimb () API

Să aruncăm o privire la cum se face un POST cu API-ul de schimb mai generic :

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. Trimiteți datele formularului

În continuare, să ne uităm la modul de trimitere a unui formular folosind metoda POST.

Mai întâi, trebuie să setăm antetul Content-Type la application / x-www-form-urlencoded.

Acest lucru asigură faptul că un șir de interogare mare poate fi trimis la server, conținând perechi nume / valoare separate prin & :

HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

Putem înfășura variabilele de formular într-un LinkedMultiValueMap :

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

Apoi, construim cererea folosind o instanță HttpEntity :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

În cele din urmă, ne putem conecta la serviciul REST apelând restTemplate.postForEntity () pe Endpoint: / foos / form

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

6. Utilizați OPȚIUNI pentru a obține operațiuni permise

În continuare, vom analiza rapid utilizarea unei cereri OPȚIUNI și explorarea operațiunilor permise pe un anumit URI folosind acest tip de cerere; API-ul este optionsForAllow :

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

7. Utilizați PUT pentru a actualiza o resursă

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

Pentru a elimina o resursă existentă, vom folosi rapid API-ul delete () :

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

9. Configurați expirarea

Putem configura RestTemplate pentru a expira prin simpla utilizare a ClientHttpRequestFactory :

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory; }

Și putem folosi HttpClient pentru opțiuni de configurare suplimentare:

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. Concluzie

În acest articol, am analizat principalele verbe HTTP, folosind RestTemplate pentru a orchestra cererile folosind toate acestea.

Dacă doriți să aflați cum să faceți autentificarea cu șablonul, consultați articolul nostru despre Auth de bază cu RestTemplate.

Implementarea tuturor acestor exemple și fragmente de cod poate fi găsită pe GitHub.