Search code examples
spring-bootspring-webclientspring5

Return the complete response using Spring WebClient


I have the following code

public ClientResponse doGet(HttpServletRequest request, URI uri) {
    return webClient.get()
            .uri(uri.toASCIIString())
            .headers(headers -> headers.putAll(processRequest(request))
            .exchange()
            .block();
}

But when I try to return this ClientResponse through the RestController as follows,

@GetMapping
@ResponseBody
public ClientResponse doGet(HttpServletRequest request) {
    ClientResponse node = service.doGet(request);
    return node;
}

I get the following error:

org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class org.springframework.web.reactive.function.client.DefaultClientResponse

Basically, the ultimate goal I want is to return the actual response back to the invoker - including the headers, body, cookies etc.

I was thinking of using ResponseEntity like follows.

public ResponseEntity<JsonNode> doGet2(HttpServletRequest request, URI uri) {

    Mono<ClientResponse> clientResponse = webClient.get()
            .uri(uri.toASCIIString())
            .headers(headers -> headers.putAll(processRequest(request))
            .exchange();

    HttpHeaders headers = clientResponse.map(resp -> resp.headers().asHttpHeaders()).block();
    JsonNode body = clientResponse.flatMap(resp -> resp.bodyToMono(JsonNode.class)).block();

    ResponseEntity<JsonNode> jsonNode = ResponseEntity.ok().headers(headers).body(body);
    return jsonNode;
}

But this is again an overkill. Is there a way to return the response directly using WebClient instead of restructuring the response?


Solution

  • ClientResponse's toEntity method converts it to a ResponseEntity<Mono> object. So I came up with the following.

    public ResponseEntity<String> doGet2(HttpServletRequest request, URI uri) {
        ClientResponse clientResponse = webClient.get()
                .uri(uri.toASCIIString())
                .headers(headers -> headers.putAll(processRequest(request)))
                .exchange()
                .block();
    
        return clientResponse.toEntity(String.class).block();
    }