Here's an example that customizes the ObjectMapper for JSON (de)serialization. Note that for streaming purposes, different encoders/decoders are being used but the principle remains the same for their configuration.

    ExchangeStrategies strategies = ExchangeStrategies
            .builder()
            .codecs(clientDefaultCodecsConfigurer -> {
                clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
                clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));

            }).build();

    WebClient webClient = WebClient.builder().exchangeStrategies(strategies).build();
Answer from Brian Clozel on Stack Overflow
Discussions

java - Custom ObjectMapper with Spring RestClient (migrating from WebClient) - Stack Overflow
A custom Jackson ObjectMapper because the application I am calling through the webclient uses kebab-case. The API exposed from my own application uses the normal pascalCase. Increase the maximum memory size the Jackson2JsonDecoder can use to read out responses. How can I migrate this code to use the RestClient of Spring ... More on stackoverflow.com
🌐 stackoverflow.com
WebClient fails to send POST body when ObjectMapper FLUSH_AFTER_WRITE_VALUE is false
Affects: Spring 5.1.6.RELEASE / Spring Boot 2.1.4.RELEASE We have a pre-existing Jackson ObjectMapper that is configured with FLUSH_AFTER_WRITE_VALUE = false. We are trying to configure the WebFlux WebClient to use this ObjectMapper for ... More on github.com
🌐 github.com
1
April 9, 2019
WebClientConfigurer "drops" ObjectMapper customizations from WebClients
This is related to spring-projects/spring-framework#23961 (comment). WebClientConfigurer configures the WebClients with the following line: More on github.com
🌐 github.com
3
November 30, 2019
How to map WebClient response to a custom DTO with mismatched fields in Spring Boot?
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full - best also formatted as code block You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit/markdown editor: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/learnjava
4
5
July 23, 2023
🌐
Baeldung
baeldung.com › home › spring › spring webflux › custom json deserialization using spring webclient
Custom JSON Deserialization Using Spring WebClient | Baeldung
February 19, 2026 - A custom ObjectMapper can be linked with WebClient at the global application level or can be associated with a specific request.
🌐
Medium
medium.com › @tepdaddy › spring-webclient-wrapper-05898d44956d
Tired of WebClient complexity: A Wrapper for Spring WebClient | by Brandon Fowler | Medium
January 9, 2024 - You can also make a client and assign a custom jackson ObjectMapper to handle serialization and deserialization
🌐
Spring
docs.spring.io › spring-boot › docs › 2.1.16.RELEASE › reference › html › boot-features-developing-web-applications.html
29. Developing Web Applications - Spring
The ObjectMapper is customized by setting the various spring.jackson.* properties or, if one exists, by a Jackson2ObjectMapperBuilder bean.
🌐
GitHub
github.com › spring-projects › spring-framework › issues › 22771
WebClient fails to send POST body when ObjectMapper FLUSH_AFTER_WRITE_VALUE is false · Issue #22771 · spring-projects/spring-framework
April 9, 2019 - Expected behavior When the Jackson ObjectMappper used for encoding/decoding in WebClient is set to FLUSH_AFTER_WRITE_VALUE = false, POST bodies should be sent to the downstream service instead of null.
Author: spring-projects
🌐
LinkedIn
linkedin.com › pulse › spring-webclient-ssl-custom-json-ivan-slavka
Spring WebClient with SSL and custom JSON serialization/deserialization
July 26, 2023 - private void client() throws Exception { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); ExchangeStrategies strategies = ExchangeStrategies .builder() .codecs(clientDefaultCodecsConfigurer -> { clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON)); clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncode
Find elsewhere
🌐
GitHub
github.com › spring-projects › spring-hateoas › issues › 1134
WebClientConfigurer "drops" ObjectMapper customizations from WebClients · Issue #1134 · spring-projects/spring-hateoas
November 30, 2019 - which ends up overriding the WebClient custom configuration (in my case, the configuration of several Jackson Modules as well as my maxInMemorySize setting). @bclozel added some logic in spring-projects/spring-framework@43e047c that should make it easier for HATEOAS to configure the WebClients without overriding existing config.
Author: spring-projects
🌐
Reddit
reddit.com › r/learnjava › how to map webclient response to a custom dto with mismatched fields in spring boot?
r/learnjava on Reddit: How to map WebClient response to a custom DTO with mismatched fields in Spring Boot?
July 23, 2023 -

I am working on a Spring Boot project and using WebClient to fetch data from an external API (TMDB). I want to map the JSON response from WebClient to my custom DTO class, but the fields in the JSON response don't exactly match the fields in my DTO.

This is my dto

public class GetMovieRequest {
private Long tmdbId;
private String title;
private List<String> genres;
private String overview;
private LocalDate releaseDate;
private Integer runtime;

}

but TMDB json has a lot of fields that I don't need to use so I can't exactly use the direct mapping bodyToMono(GetMovieRequest.class) so I use JsonNode instead:

JsonNode node = webClient.get()
    .uri([some uri]) 
    .header("Authorization", "Bearer ...") 
    .retrieve() 
    .bodyToMono(JsonNode.class) 
    .block();

but I don't think this code is optimized, is there another way?

Thanks in advanced

Top answer
1 of 3
3

After quite some time spent debugging Spring WebFlux / Jackson library code, I was able to finally find a hint to solve the issue looking at the reactive WebFlux WebClient docs. There is some custom plumbing required to make WebClient use the default auto-configured Jackson ObjectMapper. The solution is to configure the default decoder used for processing Server-Sent Events when creating new instance of the WebClient. Here is the sample code:

@Component
public class MarketDataFetcher implements CommandLineRunner {

    // ...

    private final WebClient webClient;

    public MarketDataFetcher(ObjectMapper objectMapper) {
        webClient = createWebClient(objectMapper);
    }

    private WebClient createWebClient(ObjectMapper objectMapper) {
        return WebClient.builder()
                .codecs(configurer -> configurer.defaultCodecs()
                        .serverSentEventDecoder(new Jackson2JsonDecoder(objectMapper)))
                .baseUrl(BASE_URL)
                .build();
    }
}

ObjectMapper is automatically injected by Spring, so no @Autowired annotation is needed.

It would certainly help if this could be made more explicit in the official documentation somehow. Hope this answer can be useful for someone facing similar issue!

2 of 3
1

I found in Spring Boot docs that:

the client instance is built using the WebClient.Builder bean auto-configured by Spring Boot

There is also section dedicated to WebClient customization which says:

To make the scope of any customizations as narrow as possible, inject the auto-configured WebClient.Builder and then call its methods as required.

Therefore simplest way to use configured ObjectMapper is to define WebClient bean like this:

@Bean
public WebClient webClient(WebClient.Builder builder) {
    return builder.build();
}

That is pretty unconvenient that Spring Boot doesn't do that by default given how any other stuff is already configured to use out of box but it is much better than configuring codecs by hand.

🌐
Baeldung
baeldung.com › home › spring › spring web › get list of json objects with webclient
Get List of JSON Objects with WebClient | Baeldung
January 8, 2024 - Learn how to convert a JSON Array into a Java Array of Object, Array of POJO, and a List of POJO using Spring WebClient
🌐
Spring
docs.spring.io › spring-boot › docs › 2.0.0.M3 › reference › html › boot-features-developing-web-applications.html
27. Developing web applications
The ObjectMapper will be customized based on the spring.jackson.* properties or a Jackson2ObjectMapperBuilder bean if one exists.
🌐
Spring
docs.spring.io › spring-hateoas › docs › 1.2.5 › api › org › springframework › hateoas › config › WebClientConfigurer.html
WebClientConfigurer (Spring HATEOAS 1.2.5 API)
public WebClientConfigurer(com.fasterxml.jackson.databind.ObjectMapper mapper, List<HypermediaMappingInformation> hypermediaTypes)
🌐
CodingTechRoom
codingtechroom.com › question › custom-objectmapper-spring-restclient-migration
How to Create a Custom ObjectMapper for Spring RestClient Migration from WebClient - CodingTechRoom
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); Migrating from Spring WebClient to RestClient involves the need for a custom ObjectMapper to ensure compatibility with your data formats.
Author: spring-projects
🌐
Stack Overflow
stackoverflow.com › questions › 62466358 › objectmapper-for-webclient
java - ObjectMapper for webclient - Stack Overflow
June 19, 2020 - I need to customize objectMapper; WebClient has its own ObjectMapper. Unfortunately, I do not understand how to customize objectMapper for web client and would appreciate any guidance or examples. @SpringBootApplication public class StartApplication { public static void main(String[] args) throws Exception { SpringApplication.run(ru.tularegion.mfc.StartApplication.class, args); } @Bean public ObjectMapper objectMapper() { var mapper = new ObjectMapper(); JavaTimeModule module = new JavaTimeModule(); mapper.registerModule(module); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); mapper.findAndRegisterModules(); return mapper; } } class TalonInfo { ....
🌐
DZone
dzone.com › coding › frameworks › spring webclient and java date-time fields
Spring WebClient and Java Date-Time Fields
January 23, 2020 - The underlying reason for this issue is simple: Spring Boot adds a bunch of configuration on WebClient.Builder that is lost when I have explicitly created the bean myself. Specifically, in this instance, there is a Jackson ObjectMapper created under the covers, which, by default, writes dates as timestamps.