I have this RestTemplate which I want to migrate to WebFlux client:
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
ResponseEntity<Envelope> response = restTemplate.getForEntity(url, Envelope.class);
I tried this:
Boolean webClient = WebClient.builder()
.build()
.get()
.uri("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml")
.accept(MediaType.APPLICATION_XML)
.exchangeToMono(res -> Mono.just(res.statusCode().equals(HttpStatus.OK)))
.timeout(Duration.ofSeconds(2))
.block();
I'm not clear how I can get the response and read the response as JAVA DTO. Do you know how I have to implement his code?
To make a request and retrieve a response you need to call the retrieve
function on the WebClient. Then you can parse the response Body with bodyToMono
. It's important to know that Mono is a single Object and Flux are Collection-Types
Envelope envelope = WebClient.builder()
.build()
.get()
.uri("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml")
.accept(MediaType.APPLICATION_XML)
.exchangeToMono(res -> Mono.just(res.statusCode().equals(HttpStatus.OK)))
.timeout(Duration.ofSeconds(2))
.retrieve()
.bodyToMono(Envelope.class)
.block();
There's also a nice example and explanation on this page: https://www.baeldung.com/webflux-webclient-parameters
But I would suggest you to structure your code a little bit more. For example, as you're using Spring Boot think about using that WebClientBuilder to create a WebClient as Bean, that WebClient would be configured to have a base url (https://www.ecb.europa.eu). Then you have a service where you inject that WebClient and make a call to receive your Envelope. Something like this would enable you to use the same WebCLient for different calls to the same host:
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
@Configuration
public class RestConfig {
@Bean
public WebClient ecbEuropaWebClient(WebClient.Builder webClientBuilder) {
HttpClient httpClient = HttpClient.create().tcpConfiguration(
(client) -> client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000).doOnConnected(
(connection) -> connection.addHandlerLast(
new ReadTimeoutHandler(2000, TimeUnit.MILLISECONDS))));
ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
return webClientBuilder
.baseUrl("https://www.ecb.europa.eu")
.clientConnector(connector)
.build();
}
}
@Service
public class EcbEuropaService {
@Autowired
private WebClient ecbEuropaWebClient;
public Envelope getEnvelope() {
return ecbEuropaWebClient.get()
.uri(uriBuilder -> uriBuilder.path("/stats/eurofxref/eurofxref-daily.xml").build())
.accept(MediaType.APPLICATION_XML).retrieve().bodyToMono(Envelope.class).block();
}
}