Webclient returning Optional.empty() on not found response
Asked Answered
V

2

6

I'm trying to make WebClient return an Optional.empty() when I get a 404, not found, from the server. But instead I get a Optional with a User object with all properties set to null.

What am I missing?

@Override
public Optional<User> getUser(Username username) {
    return webClient
            .get()
            .uri(buildUrl(username))
            .retrieve()
            .onStatus(HttpStatus.NOT_FOUND::equals, response -> Mono.empty())
            .onStatus(HttpStatus::is4xxClientError, response -> createError(response, CLIENTERROR))
            .onStatus(HttpStatus::is5xxServerError, response -> createError(response, SERVRERROR))
            .bodyToMono(User.class)
            .blockOptional();
}
Vocation answered 18/5, 2020 at 10:57 Comment(0)
U
20

You can make use of onError* functions from Mono to handle these cases.

onErrorResume to create a empty/error Mono on exception and onErrorMap to transform exception to a different exception type.

For example:

@Override
public Optional<User> getUser(Username username) {
    return webClient
            .get()
            .uri(buildUrl(username))
            .retrieve()
            .onStatus(httpStatus -> httpStatus.is4xxClientError() && httpStatus != HttpStatus.NOT_FOUND, response -> createError(response, CLIENTERROR))
            .onStatus(HttpStatus::is5xxServerError, response -> createError(response, SERVRERROR))
            .bodyToMono(User.class)
            .onErrorResume(WebClientResponseException.NotFound.class, notFound -> Mono.empty())
            .blockOptional();
}
Unduly answered 10/8, 2020 at 14:51 Comment(2)
Note that the "onStatus" calls are not necessary to solve the original problem. The "onErrorResume" call does the requested job.Asthmatic
Shame there isnt a built in feature in the Spring WebClient to allow this to workBaltic
L
2

Have a look at the sample code from WebClient Javadoc (javadoc). It does exactly that using Mono's onErrorResume Method:

 webClient.get()
   .uri("https://example.com/account/123")
   .retrieve()
   .bodyToMono(Account.class)
   .onErrorResume(WebClientResponseException.class,
        ex -> ex.getRawStatusCode() == 404 ? Mono.empty() : Mono.error(ex));
Lie answered 7/5, 2021 at 10:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.