Estás viendo una versión antigua de esta página. Ve a la versión actual.

Comparar con el actual Ver el historial de la página

« Anterior Versión 6 Siguiente »


Previamente utilizábamos RestTemplate para hacer un cliente REST en Spring Boot, pero ésta se va a quedar obsoleta, por lo que a partir de ahora tendremos que usar WebClient.

Dependencias

IMPORTANTE

Para utilizar WebClient la versión del parent de nuestra aplicación (está en el pom.xml) debe ser igual o superior a 2.6.0, si no pueden surgir conflictos con otras librerías.

Tendremos que añadir la siguiente dependencia a nuestro pom.xml:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

Crear un WebClient

Para crear un WebClient, tendremos que crearlo como un bean en un archivo de configuración. Nos crearemos una clase para ello, WebClientConfig, donde crearemos cada webClient que necesitemos de esta manera, con la url correspondiente:

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient(WebClient.Builder webClientBuilder) {
        return webClientBuilder
                .baseUrl("https://apidesa.um.es/acade/expedienteacademico-api/private/v1.0").build();
    }
 
}

Si tenemos un solo WebClient, simplemente lo usaremos con @Autowired, si tenemos varios, además de @Autowired tendremos que añadir @Qualifier("nombre del bean").

Añadir headers por defecto

Si queremos añadir headers por defecto, como por ejemplo que el tipo del body es JSON, y que acepta también una respuesta en JSON, lo haremos así:

return webClientBuilder
        .baseUrl("https://apidesa.um.es/acade/expedienteacademico-api/private/v1.0")
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
        .build();

Hacer una petición y recibir una respuesta

Una vez creado el WebClient, podremos hacer peticiones indicando el método REST, la uri a la que se llama, los headers que queramos añadirle (si queremos añadirle alguno), el body que le pasamos si es necesario (con Mono.just(..) para pasarle el objeto que sea, y su clase), y obtener la respuesta:

String response = webClient.post()
        .uri("/recurso")
		.header("nombreHeader", "Valor")
        .body(Mono.just(Objeto), TipoObjeto.class)
        .retrieve()
        .bodyToMono(String.class)
        .block();

También podemos indicar un timeout para nuestra llamada:

String response = webClient.post()
        .uri("/recurso")
		.header("nombreHeader", "Valor")
        .body(Mono.just(Objeto), TipoObjeto.class)
        .retrieve()
        .bodyToMono(String.class)
		.timeout(Duration.ofSeconds(3))
        .block();

¡Ojo! Por defecto, las llamadas con WebClient son asíncronas, no bloqueantes. La instrucción block() del final sirve para hacerlas bloqueantes, para esperar a la respuesta antes de seguir.

Body con Content-Type: application/x-www-form-urlencoded

Para este caso, hay que meter el body utilizando BodyInserters.fromFormData, pasándole un MultiValueMap. Por ejemplo:

        MultiValueMap<String, String> bodyForm = new LinkedMultiValueMap<>();
        bodyForm.add("login", "correo@prueba.com");
        bodyForm.add("clave", "AAERRasdfasdf1asd2asdfasdf:34adsad");
        bodyForm.add("nomape", "MESSI");
        bodyForm.add("tipo", "externa");
        bodyForm.add("validar", "no");

        String response = webClient.post()
                .uri(metodo).body(BodyInserters.fromFormData(bodyForm))
                .retrieve()
                .bodyToMono(String.class)
                .block();


Gestionar código de respuesta

Para gestionar llamadas fallidas, o según el código que se obtenga, utilizamos onStatus:

String response = webClient.post()
        .uri("/recurso")
		.header("nombreHeader", "Valor")
        .body(Mono.just(Objeto), TipoObjeto.class)
        .retrieve()
		.onStatus(HttpStatus::is5xxServerError, clientResponse -> {
			log.error("Error, código {}", clientResponse.statusCode());
			throw new UnaExcepcion("HTTP Status 500 error");
		})
        .bodyToMono(String.class)
		.timeout(Duration.ofSeconds(3))
        .block();

A destacar es que no acepta los códigos de error con las constantes tipo HttpStatus.FORBIDDEN, pide un predicado de tipo HttpStatus::metodo. Normalmente se utilizarán métodos como el mostrado ahí para error 500 (5xx más bien), y también da opción para 4xx (is4xxClientError), para 3xx (is3xxRedirection), o para 2xx (is2xxSuccessful). Si autocompletamos podremos ver todas las opciones.

Documentación relacionada

  • Sin etiquetas