web-dev-qa-db-fra.com

Comment extraire l'en-tête de réponse et le code d'état de Spring 5 WebClient ClientResponse

Je suis nouveau dans le framework Spring Reactive et j'essaie de convertir le code Springboot 1.5.x en Springboot 2.0. Je dois retourner l'en-tête de réponse après un filtrage, un corps et un code d'état de Spring 5 WebClient ClientResponse. Je ne veux pas utiliser la méthode block () car elle la convertira en appel de synchronisation. Je peux obtenir assez facilement responsebody en utilisant bodyToMono. De plus, j'obtiens le code d'état, les en-têtes et le corps si je retourne simplement ClientResponse mais je dois traiter la réponse en fonction des paramètres statusCode et en-tête. J'ai essayé de m'abonner, de FlatMap etc. mais rien ne fonctionne.

Par exemple. - Le code ci-dessous renverra le corps de la réponse

Mono<String> responseBody =  response.flatMap(resp -> resp.bodyToMono(String.class));

Mais un paradigme similaire ne fonctionne pas pour obtenir les en-têtes statusCode et Response. Quelqu'un peut-il m'aider à extraire les paramètres de statusCode et d'en-tête à l'aide du framework réactif Spring 5?.

10
Renus11

Vous pouvez utiliser la fonction d'échange de webclient par exemple.

Mono<String> reponse = webclient.get()
.uri("https://stackoverflow.com")
.exchange()
.doOnSuccess(clientResponse -> System.out.println("clientResponse.headers() = " + clientResponse.headers()))
.doOnSuccess(clientResponse -> System.out.println("clientResponse.statusCode() = " + clientResponse.statusCode()))
.flatMap(clientResponse -> clientResponse.bodyToMono(String.class));

alors vous pouvez convertir bodyToMono etc.

4
Kevin Hussey

Vous pouvez configurer Spring Boot> = 2.1.0 pour enregistrer la demande et la réponse si vous utilisez le WebClient:

spring.http.log-request-details: true
logging.level.org.springframework.web.reactive.function.client.ExchangeFunctions: TRACE

Comme décrit dans les documents de démarrage de sprint , si vous souhaitez que les en-têtes soient également enregistrés, vous devez ajouter

Consumer<ClientCodecConfigurer> consumer = configurer ->
    configurer.defaultCodecs().enableLoggingRequestDetails(true);

WebClient webClient = WebClient.builder()
    .exchangeStrategies(ExchangeStrategies.builder().codecs(consumer).build())
    .build();

Mais sachez que cela peut enregistrer des informations sensibles.

2
Tobske

Je devais également vérifier les détails de la réponse (en-têtes, statut, etc.) et le corps.

La seule façon dont j'ai pu le faire était d'utiliser .exchange() avec deux subscribe() comme exemple suivant:

    Mono<ClientResponse> clientResponse = WebClient.builder().build()
            .get().uri("https://stackoverflow.com")
            .exchange();

    clientResponse.subscribe((response) -> {

        // here you can access headers and status code
        Headers headers = response.headers();
        HttpStatus stausCode = response.statusCode();

        Mono<String> bodyToMono = response.bodyToMono(String.class);
        // the second subscribe to access the body
        bodyToMono.subscribe((body) -> {

            // here you can access the body
            System.out.println("body:" + body);

            // and you can also access headers and status code if you need
            System.out.println("headers:" + headers.asHttpHeaders());
            System.out.println("stausCode:" + stausCode);

        }, (ex) -> {
            // handle error
        });
    }, (ex) -> {
        // handle network error
    });

J'espère que ça aide. Si quelqu'un connaît une meilleure façon de le faire, veuillez nous le faire savoir.

2
Rafael Amaral

Pour le code d'état, vous pouvez essayer ceci:

Mono<HttpStatus> status = webClient.get()
                .uri("/example")
                .exchange()
                .map(response -> response.statusCode());

Pour les en-têtes:

Mono<HttpHeaders> result = webClient.get()
                .uri("/example")
                .exchange()
                .map(response -> response.headers().asHttpHeaders());
1
Shreya Sharma