Home > Net >  How to call a method inside onStatus() in Spring Webclient
How to call a method inside onStatus() in Spring Webclient

Time:10-05

Currently, I just throw an exception in onStatus() when the response code is 4XX or 5XX. However, I want to call another service ( a compensating transaction to undo the changes) and then throw an Exception.

webclient
            .post()
            .uri(url, chargeSeqId)
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)
            .acceptCharset(Charset.forName("UTF-8"))
            .header(HttpHeaders.AUTHORIZATION, "Bearer "   token)
            .body(BodyInserters.fromValue(pojos))
            .retrieve()
            .onStatus(HttpStatus::is4xxClientError,
                    res -> res.bodyToMono(String.class)
                            .flatMap(error -> Mono.error(new DataValidationException(error))))
            .onStatus(HttpStatus::is5xxServerError,
                    res -> res.bodyToMono(String.class).flatMap(error -> Mono.error(new SystemException(error))))
            .bodyToMono(MyPojos[].class)
            .block();

I want to call the following method when the response code is either 4XX or 5XX before throwing either DataValidationException() or SystemException().

    private String deleteTransaction(Integer transactionID) {
        Mono<String> result = webclient.delete()
                .uri(uriBuilder -> uriBuilder
                        .path(url   "/"   transactionID   "/delete").build())
                .header(HttpHeaders.AUTHORIZATION, "Bearer "   clientProfile.getJwt().getTokenValue()).retrieve()
                .bodyToMono(String.class);
        String ack = result.block();
        return ack;
}

CodePudding user response:

Instead of calling block inside another block you can make deleteTransaction method return mono.

private Mono<String> deleteTransaction(Integer transactionID) {
        return webclient.delete()
                .uri(uriBuilder -> uriBuilder
                        .path(url   "/"   transactionID   "/delete").build())
                .header(HttpHeaders.AUTHORIZATION, "Bearer "   clientProfile.getJwt().getTokenValue()).retrieve()
                .bodyToMono(String.class);
}

Then you can call this method in the required places in non blocking way. Also as I donot know what you actually want to pass to deleteTransaction method, I have passed chargeSeqId to it.


     .onStatus(HttpStatus::is4xxClientError,
             res -> {
                    var ackMono = deleteTransaction(chargeSeqId); // replace with required input
                    var resBodyMono = res.bodyToMono(String.class);
                    return Mono.zip(ackMono, resBodyMono, (ack,resBody)->Mono.error(new DataValidationException(resBody)));
                    })
                             

This can be done for is5xxServerError as well.

  • Related