La guía de RestTemplate

1. Información general

En este tutorial, vamos a ilustrar la amplia gama de operaciones en las que Spring REST Client ( RestTemplate ) se puede usar y usar bien.

Para el lado de la API de todos los ejemplos, ejecutaremos el servicio RESTful desde aquí.

2. Aviso de baja

A partir de Spring Framework 5, junto con la pila de WebFlux, Spring introdujo un nuevo cliente HTTP llamado WebClient .

WebClient es un cliente HTTP alternativo y moderno a RestTemplate . No solo proporciona una API síncrona tradicional, sino que también admite un enfoque eficiente sin bloqueo y asíncrono.

Dicho esto, si estamos desarrollando nuevas aplicaciones o migrando una antigua, es una buena idea utilizar WebClient . En el futuro, RestTemplate quedará obsoleto en versiones futuras.

3. Utilice GET para recuperar recursos

3.1. Obtenga JSON simple

Comencemos de manera simple y hablemos de las solicitudes GET, con un ejemplo rápido usando la 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));

Tenga en cuenta que tenemos acceso completo a la respuesta HTTP , por lo que podemos hacer cosas como verificar el código de estado para asegurarnos de que la operación fue exitosa o trabajar con el cuerpo real de la respuesta:

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

Estamos trabajando con el cuerpo de respuesta como una cadena estándar aquí y usando Jackson (y la estructura de nodo JSON que proporciona Jackson) para verificar algunos detalles.

3.2. Recuperando POJO en lugar de JSON

También podemos asignar la respuesta directamente a un DTO de recursos:

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

Ahora podemos simplemente usar la API getForObject en la plantilla:

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

4. Use HEAD para recuperar encabezados

Ahora echemos un vistazo rápido al uso de HEAD antes de pasar a los métodos más comunes.

Vamos a utilizar la API headForHeaders () aquí:

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

5. Utilice POST para crear un recurso

Para crear un nuevo recurso en la API, podemos hacer un buen uso de las API postForLocation () , postForObject () o postForEntity () .

El primero devuelve el URI del recurso recién creado, mientras que el segundo devuelve el propio recurso.

5.1. La API postForObject ()

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. La API postForLocation ()

De manera similar, echemos un vistazo a la operación que, en lugar de devolver el Recurso completo, solo devuelve la Ubicación de ese Recurso recién creado:

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

5.3. La API de exchange ()

Echemos un vistazo a cómo hacer un POST con la API de intercambio más genérica :

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. Enviar datos del formulario

A continuación, veamos cómo enviar un formulario mediante el método POST.

Primero, debemos establecer el encabezado Content-Type en application / x-www-form-urlencoded.

Esto asegura que se pueda enviar una cadena de consulta grande al servidor, que contiene pares de nombre / valor separados por & :

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

Podemos envolver las variables del formulario en un LinkedMultiValueMap :

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

A continuación, construimos la solicitud utilizando una instancia de HttpEntity :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

Finalmente, podemos conectarnos al servicio REST llamando a restTemplate.postForEntity () en el Endpoint: / foos / form

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

6. Utilice OPCIONES para obtener operaciones permitidas

A continuación, vamos a echar un vistazo rápido al uso de una solicitud OPTIONS y explorar las operaciones permitidas en un URI específico usando este tipo de solicitud; la API es optionsForAllow :

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

7. Utilice PUT para actualizar un recurso

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

Para eliminar un recurso existente, haremos un uso rápido de la API delete () :

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

9. Configurar el tiempo de espera

Podemos configurar RestTemplate para que se agote el tiempo de espera simplemente usando ClientHttpRequestFactory :

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

Y podemos usar HttpClient para más opciones de configuración:

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. Conclusión

En este artículo, repasamos los principales verbos HTTP, usando RestTemplate para orquestar las solicitudes usando todos estos.

Si desea profundizar en cómo realizar la autenticación con la plantilla, consulte nuestro artículo sobre autenticación básica con RestTemplate.

La implementación de todos estos ejemplos y fragmentos de código se puede encontrar en GitHub.