NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the org.springframework.web.reactive.client.WebClient which has a more modern API and supports sync, async, and streaming scenarios.
WebClient vs RestTemplate
WebClient is Non-Blocking Client, RestTemplate is Blocking Client.RestTemplate uses Java Servlet API and is therefore synchronous and blocking. In contrast, WebClient is asynchronous and will not block the executing thread while waiting for the response to come back. Only when the response is ready will the notification be produced.
RestTemplate supports only synchronous calls. WebClient supports asynchronous as well as synchronous calls. Use block() for synchronous calls in WebClient.
Let’s look how we can use WebClient to consume the RESTful APIs.
Mono is used for handling zero or one result, the Flux is used to handle zero to many results
Java Code
packagecom.spring.rest.config;importorg.springframework.boot.CommandLineRunner;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.http.HttpHeaders;importorg.springframework.web.reactive.function.client.ClientResponse;importorg.springframework.web.reactive.function.client.WebClient;importcom.spring.rest.model.Student;importreactor.core.publisher.Flux;importreactor.core.publisher.Mono;@SpringBootApplicationpublicclassApplicationimplementsCommandLineRunner{publicstaticvoidmain(String[] args){SpringApplication.run(Application.class, args);}@Overridepublicvoidrun(String...args)throwsException{String baseUrl = ″http://localhost:8080″;System.out.println("Started");// Building webClient - specify baseURl and defaultHeaders if any.WebClient webClient =WebClient.builder().baseUrl(baseUrl).defaultHeader(HttpHeaders.USER_AGENT,"WebClient").defaultHeader(HttpHeaders.CONTENT_TYPE,"application/json").build();// Fetching list of students using retrieve asynchronously - mapping responseBody to FluxFlux<Student> studentFlux = webClient.get().uri("/students").retrieve().bodyToFlux(Student.class);
studentFlux.subscribe(student ->System.out.println("Flux without block:"+ student));// Fetching student with id =1 using retrieve asynchronously - mapping responseBody to MonoMono<Student> studentMono = webClient.get().uri("/students/1").retrieve().bodyToMono(Student.class);
studentMono.subscribe(student ->System.out.println("Mono without block:"+ student));// Fetching student with id =2 using exchange asynchronously - //mapping responseBody to Mono and getting the response headers and statusMono<ClientResponse> clientResponse = webClient.get().uri("/students/2").exchange();
clientResponse.subscribe(x ->System.out.println("Exchange Reponse Headers = "+ x.headers()));
clientResponse.subscribe(x ->System.out.println("Exchange Response Status Code = "+ x.statusCode()));
clientResponse.flatMap(x -> x.bodyToMono(Student.class)).subscribe(student ->System.out.println("Using Exchange:"+ student));// Fetching student with id =2 using retrieve synchronously by using the method blockStudent studentAsync = webClient.get().uri("/students/2").retrieve().bodyToMono(Student.class).block();System.out.println("Using Block:"+ studentAsync);System.out.println("End");}}
Output
StartedExchangeReponseHeaders=org.springframework.web.reactive.function.client.DefaultClientResponse$DefaultHeaders@13caef6fExchangeResponseStatusCode=200 OK
UsingExchange:Student[id=2, name=rochit, age=16, weight=55]UsingBlock:Student[id=2, name=rochit, age=16, weight=55]EndMono without block:Student[id=1, name=gyan, age=18, weight=70]Flux without block:Student[id=1, name=gyan, age=18, weight=70]Flux without block:Student[id=2, name=rochit, age=16, weight=55]Flux without block:Student[id=8, name=ravi, age=17, weight=65]Flux without block:Student[id=9, name=TEJA, age=14, weight=58]Flux without block:Student[id=11, name=VIKU, age=16, weight=44]Flux without block:Student[id=12, name=Ajay, age=16, weight=44]Flux without block:Student[id=15, name=Ramu, age=18, weight=47]Flux without block:Student[id=20, name=Sachin, age=14, weight=50]Flux without block:Student[id=21, name=Ramesh, age=14, weight=50]Flux without block:Student[id=23, name=Prabhakar, age=14, weight=50]Flux without block:Student[id=30, name=Mantu, age=15, weight=50]