Hello,

I'm using Spring Boot 3.3.6 with WebFlux. I wanted to make sure that my deserialized ZonedDateTime objects from @RequestBody parameters retained the offset. Should be simple enough, so I updated the my @Primary ObjectMapper bean definition to configure DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE to false.

However, when I stepped in to the code, I could see it was using an ad-hoc instance of the ObjectMapper from the default constructor for Jackson2JsonDecoder. Is there any reason it shouldn't use the primary by default? I had to make a new configuration class to get this to work:

@Bean
@Primary
ObjectMapper objectMapper() {       
...
}


@Configuration
public class ServerCodecConfig implements WebFluxConfigurer {

    private final ObjectMapper objectMapper;

    public ServerCodecConfig(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper));
        configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper));
    }
}

Incidentally, Spring Boot creates a JacksonCodecConfiguration with the properly wired ObjectMapper, but the customize callback function is never actually called. These CodecCustomizers seem to be used in the WebFluxAutoConfiguration class, but not in the DelegatingWebFluxConfiguration.

Creating shared instance of singleton bean org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration$JacksonCodecConfiguration'

Comment From: wilkinsona

It works for me. The customizer is applied by WebFluxConfig in WebFluxAutoConfiguration as it should be. I would guess that you've done something in your app that causes the WebFlux auto-configuration to back off. Perhaps you've used @EnableWebFlux or sub-classed WebFluxConfigurationSupport somewhere.

If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

Comment From: seabamirum

You're right, I was using @EnableWebFlux and after removing that it works as expected.

However, what sent me down this rabbit hole was that when @EnableWebFlux is used, the JacksonCodecConfiguration still requires an ObjectMapper instance in order for the application to start, but then it's never used (the configurer callback in the CodecCustomizer is never executed) . Perhaps JacksonCodecConfiguration needs a @ConditionalOnMissingBean(WebFluxConfigurationSupport.class) annotation to prevent this dependency when @EnableWebFlux is present?

Comment From: bclozel

Thanks for letting us know. This is the expected behavior as this is the way for applications to let Spring Boot know that they want to fully control the web layer setup.

The CodecsAutoConfiguration happens at a lower level and is useful for both reactive clients and servers. The relationship goes the other way around: the WebFluxAutoConfiguration is ordered after the CodecsAutoConfiguration because it needs what's been produced by it.

I'm not sure what problem you're having but it sounds like your application is sending mixed signals to the Spring Boot auto-configuration and you're not getting the results you're expecting. Maybe asking a question on StackOverflow would help? I think that showing a minimal setup, explaining what you're seeing and what you'd like to see instead, would allow people to help you.

Comment From: seabamirum

I updated the title to be clearer. It still feels like a bug, but oh well.

Comment From: bclozel

The issue title states exactly how things are expected to work and documented. I don't see any bug here.

Again, using @EnableWebflux means that you're taking full control over the web server configuration. You might still rely on the auto-configuration for WebClient, for example. The reactive HTTP client will use the auto-configured codecs, including the Jackson one.

Applying your suggestion would do two things: 1. create a dependency cycle between the codecs and web server auto-configurations and would deadlock 2. break a lot of existing apps that want to fully control the web server configuration and yet still use the auto-configured codecs for other means (HTTP client, GraphQL, integration, etc)

I hope this makes sense.