Ръководството за RestTemplate

1. Общ преглед

В този урок ще илюстрираме широкия набор от операции, при които Spring REST Client - RestTemplate - може да бъде използван и използван добре.

За страната на API на всички примери ще стартираме услугата RESTful оттук.

2. Известие за оттегляне

От Spring Framework 5, заедно със стека WebFlux, Spring представи нов HTTP клиент, наречен WebClient .

WebClient е модерен, алтернативен HTTP клиент на RestTemplate . Той не само осигурява традиционен синхронен API, но също така поддържа ефективен неблокиращ и асинхронен подход.

Въпреки това, ако разработваме нови приложения или мигрираме старо, е добра идея да използваме WebClient . Придвижвайки се напред, RestTemplate ще бъде остарял в бъдещите версии.

3. Използвайте GET за извличане на ресурси

3.1. Вземете обикновен JSON

Нека започнем просто и да поговорим за GET заявки, с бърз пример, използващ API на 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));

Забележете, че имаме пълен достъп до HTTP отговора , така че можем да правим неща като да проверяваме кода на състоянието, за да се уверим, че операцията е била успешна или да работим с действителното тяло на отговора:

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

Тук работим с тялото на отговора като стандартен String и използваме Jackson (и структурата на възела JSON, която Jackson предоставя), за да проверим някои подробности.

3.2. Извличане на POJO Вместо JSON

Също така можем да картографираме отговора директно към DTO на ресурса:

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

Сега можем просто да използваме API на getForObject в шаблона:

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

4. Използвайте HEAD за извличане на заглавки

Нека сега да разгледаме бързо използването на HEAD, преди да преминем към по-често срещаните методи.

Ще използваме API на headForHeaders () тук:

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

5. Използвайте POST, за да създадете ресурс

За да създадем нов ресурс в API, можем да използваме добре API-та postForLocation () , postForObject () или postForEntity () .

Първият връща URI на новосъздадения ресурс, докато вторият връща самия ресурс.

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

По същия начин, нека да разгледаме операцията, която вместо да върне пълния ресурс, просто връща местоположението на този новосъздаден ресурс:

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

5.3. В замяна () API

Нека да разгледаме как да направите POST с по-общия API за обмен :

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. Подаване на данни от формуляра

След това нека разгледаме как да изпратите формуляр, използвайки метода POST.

Първо, трябва да зададем заглавката Content-Type на application / x-www-form-urlencoded.

Това гарантира, че голям низ за заявка може да бъде изпратен до сървъра, съдържащ двойки име / стойност, разделени с & :

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

Можем да обгърнем променливите на формата в LinkedMultiValueMap :

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

След това изграждаме заявката, като използваме екземпляр HttpEntity :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

И накрая, можем да се свържем с услугата REST, като извикаме restTemplate.postForEntity () на Крайната точка: / foos / form

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

6. Използвайте ОПЦИИ, за да получите разрешени операции

След това ще направим бърз поглед върху използването на заявка OPTIONS и изследване на разрешените операции на конкретен URI, използвайки този вид заявка; API е опцииForAllow :

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

7. Използвайте PUT, за да актуализирате ресурс

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

За да премахнем съществуващ Ресурс, ще използваме бързо API на delete () :

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

9. Конфигурирайте времето за изчакване

Можем да конфигурираме RestTemplate за изчакване, като просто използваме ClientHttpRequestFactory :

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

И можем да използваме HttpClient за допълнителни опции за конфигуриране:

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. Заключение

В тази статия разгледахме основните HTTP глаголи, използвайки RestTemplate за организиране на заявки, използвайки всички тези.

Ако искате да разберете как да направите удостоверяване с шаблона, вижте нашата статия за Basic Auth с RestTemplate.

Прилагането на всички тези примери и кодови фрагменти може да бъде намерено в GitHub.