Вернуть полный ответ с помощью Spring WebClient

У меня есть следующий код

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

Но когда я пытаюсь вернуть этот ClientResponse через RestController следующим образом,

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

Я получаю следующую ошибку:

org.springframework.http.converter.HttpMessageNotWritableException: не найден преобразователь для возвращаемого значения типа: class org.springframework.web.reactive.function.client.DefaultClientResponse

По сути, конечная цель, которую я хочу, - это вернуть фактический ответ обратно вызывающей стороне, включая заголовки, тело, файлы cookie и т. Д.

Я думал об использовании ResponseEntity следующим образом.

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;
}

Но это опять перебор. Есть ли способ вернуть ответ напрямую с помощью WebClient вместо реструктуризации ответа?


person Philip John    schedule 25.09.2020    source источник


Ответы (2)


Метод toEntity ClientResponse преобразует его в объект ResponseEntity ‹Mono›. Итак, я придумал следующее.

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();
}
person Philip John    schedule 25.09.2020

Обычно, когда вы возвращаете pojo как responseBody, spring требует, чтобы класс имел геттеры для полей. Теперь, поскольку вы не возвращаете принадлежащий вам класс, вы не можете их добавить.
Другим решением может быть добавление библиотеки в ваш проект, которая преобразует pojo в json. это может сделать трюк:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.0</version>
</dependency>
person Nir Levy    schedule 25.09.2020
comment
На самом деле я добавил зависимость Джексона, но она не исправила ее. - person Philip John; 25.09.2020