Issue
We are moving our code from RestTemplate to WebClient to achieve non-blocking call and we are almost done it. But, after moving our code to WebClient we facing issue as when client makes call to our API, we are responding with blank response. Although, our backend client has response.
I tried, ofResponseProcessor
, but this isn't executing it seems (as logs inside method is not getting printed)
Here is my code :
Mono<ClientResponse> clientResponse = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(clientOptions))
.filter(processResponse(httpResponse)) <-- passing HttpServletResponse
.baseUrl("https://xxxxx.xxxx/")
.build()
.get()
.uri("/getresult")
.exchange();
logger.info("======Thread Completed=====");
Now, our processResponse will write response from ClientResponse
to HttpServletResponse
public ExchangeFilterFunction processResponse(HttpServletResponse resp) {
return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
logger.info("======Writing Response=====");
writeResponse(clientResponse,resp); //writing response to servletresponse
return Mono.just(clientResponse);
});
}
I don't see ======Writing Response=====
in my console log.
I also tried using subscribe
on ClientResponse
, but I'm still getting blank response until I put Thread.sleep
.
Can anyone help me about what am I missing here ?
====Update=====
private void writeResponse(ClientResponse clientResponse, HttpServletResponse resp){
clientResponse.bodyToMono(String.class)
.subscribe(consumer -> {
....
....
IOUtils.copy(new ByteArrayInputStream(consumer.getBytes()),resp.getOutputStream());
}
...
);
}
Solution
Because you are using non-blocking calls the thread that executes the API call (and the subscribe block) is different from the main thread, so the main thread will continue executing the rest of code and returns the response although the other thread is not finished yet.
So you have two options make your API reactive so you can return the Mono object directly and is the client of the API the one that subscribes to it, or if you want synchronous (non-reactive) API you have to call the block method of the Mono object to allow the main thread to obtain the result of the external call
Answered By - JArgente
Answer Checked By - David Goodson (JavaFixing Volunteer)