O Guia do RestTemplate

O Guia do RestTemplate

*1. Visão geral *

Neste tutorial, ilustraremos a ampla gama de operações em que o Spring REST Client - RestTemplate - pode ser usado e usado bem.

Para o lado da API de todos os exemplos, executaremos o serviço RESTful em aqui.

Leitura adicional:

https://www..com/how-to-use-resttemplate-with-basic-authentication-in-spring [Autenticação básica com o RestTemplate]

Como fazer a autenticação básica com o Spring RestTemplate.

https://www..com/resttemplate-digest-authentication [RestTemplate com autenticação Digest]

Como configurar a autenticação Digest para o Spring RestTemplate usando o HttpClient 4.

https://www..com/spring-boot-testresttemplate [Explorando o Spring Boot TestRestTemplate]

Aprenda a usar o novo TestRestTemplate no Spring Boot para testar uma API simples.

===* 2. Use GET para recuperar recursos *

====* 2.1 Obtenha JSON simples *

Vamos começar de maneira simples e falar sobre solicitações GET - com um exemplo rápido usando a API _getForEntity () _:

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

Observe que temos acesso total à resposta HTTP - para que possamos fazer coisas como verificar o código de status para garantir que a operação tenha sido realmente bem-sucedida ou trabalhar com o corpo real da resposta:

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

Estamos trabalhando com o corpo da resposta como uma String padrão aqui - e usando Jackson (e a estrutura de nós JSON que Jackson fornece) para verificar alguns detalhes.

====* 2.2 Recuperando POJO em vez de JSON *

Também podemos mapear a resposta diretamente para um DTO de recursos - por exemplo:

public class Foo implements Serializable {
    private long id;

    private String name;
   //standard getters and setters
}

Agora - podemos simplesmente usar a API getForObject no modelo:

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

===* 3. Use HEAD para recuperar cabeçalhos *

Agora, vamos dar uma olhada rápida no uso do HEAD antes de passar para os métodos mais comuns - usaremos a API _headForHeaders () _ aqui:

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

===* 4. Use o POST para criar um recurso *

Para criar um novo Recurso na API - podemos fazer bom uso das APIs _postForLocation () _, _postForObject () _ ou _postForEntity () _.

O primeiro retorna o URI do Recurso recém-criado, enquanto o segundo retorna o próprio Recurso.

====* 4.1 A API postForObject __ *

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

====* 4.2 A API postForLocation *

Da mesma forma, vamos dar uma olhada na operação que - em vez de retornar o Recurso completo, apenas retorna o Location desse Recurso recém-criado:

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

====* 4.3 A API exchange __ *

Vamos dar uma olhada em como fazer um POST com a API exchange mais genérica:

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

====* 4.4 Enviar dados do formulário *

A seguir, veremos como enviar um formulário usando o método POST.

Primeiro, precisamos definir o cabeçalho "Content-Type" como application/x-www-form-urlencoded.

Isso garante que uma string de consulta grande possa ser enviada ao servidor, contendo pares de nome/valor separados por ‘_ & _‘:

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

Podemos agrupar as variáveis ​​de formulário em um _https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/LinkedMultiValueMap.html [LinkedMultiValueMap] _:

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

Em seguida, criamos a solicitação usando uma HttpEntity:

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

Finalmente, podemos conectar-se ao serviço REST chamando https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#postForEntity-java.net.URI -java.lang.Object-java.lang.Class - [_ restTemplate.postForEntity () ] no nó de extremidade: / foos/form_

ResponseEntity<String> response = restTemplate.postForEntity(
  fooResourceUrl+"/form", request , String.class);

assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

===* 5. Use OPTIONS para obter operações permitidas *

A seguir, veremos rapidamente o uso de uma solicitação OPTIONS e exploramos as operações permitidas em um URI específico usando esse tipo de solicitação; a API é optionsForAllow:

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

===* 6. Use PUT para atualizar um recurso *

Em seguida, começaremos a analisar o PUT - e, mais especificamente, a API exchange desta operação, devido à API template.put ser bastante direta.

====* 6.1 PUT simples com * exchange

Começaremos com uma operação simples de PUT na API - e tenha em mente que a operação não está retornando ninguém de volta ao cliente:

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

6.2 PUT com .exchange e uma solicitação de retorno de chamada

Em seguida, usaremos um retorno de chamada de solicitação para emitir um PUT.

Vamos preparar o retorno de chamada - onde podemos definir todos os cabeçalhos necessários, bem como um corpo de solicitação:

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

Em seguida, criamos o recurso com a solicitação POST:

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

E então atualizamos o Recurso:

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

*7. Use DELETE para remover um recurso *

Para remover um Recurso existente, faremos um breve trabalho com a API _delete () _:

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

===* 8. Configurar tempo limite *

Podemos configurar RestTemplate para expirar usando simplesmente ClientHttpRequestFactory - da seguinte maneira:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

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

E podemos usar HttpClient para mais opções de configuração - da seguinte maneira:

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

===* 9. Conclusão *

Examinamos os principais verbos HTTP, usando RestTemplate para orquestrar solicitações usando tudo isso.

Se você quiser descobrir como fazer autenticação com o modelo - confira meu link de redação:/como usar o resttemplate com autenticação básica na primavera [em Autenticação básica com RestTemplate].

A implementação de todos esses exemplos e trechos de código* pode ser encontrada em my projeto GitHub * - este é um projeto baseado no Maven, portanto deve ser fácil de importar e executar como está.