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 3 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

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 creaar un WebClient, utilizaremos WebClient.builder(), pasándole a continuación la url base la que queremos llamar:

WebClient webClient = WebClient.builder()
        .baseUrl("https://unaapi.com")
        .build();

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í:

WebClient webClient = WebClient.builder()
        .baseUrl("https://unaapi.com")
        .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