在Spring Webflux中修改/覆盖/扩展内置Jackson 2 ObjectMapper的建议方法是什么?

时间:2017-12-21 12:27:40

标签: spring spring-webflux reactor-netty

目前我有杰克逊图书馆的简约 Spring / Netty Reactor / Web Flux 项目

Futures.allAsList

的build.gradle:

FutureCallback::onFailure

Controller类工作正常(它返回带有DTO类型的@Configuration public class EmbeddedSpringServer extends DelegatingWebFluxConfiguration { @Bean MyController controller() { return new AdminController(); } public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EmbeddedSpringServer.class); HttpHandler handler = WebHttpHandlerBuilder.applicationContext(applicationContext).build(); ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler); HttpServer.create("0.0.0.0", 8082).newHandler(adapter).subscribe(); applicationContext.registerShutdownHook(); } } )。 因为Jackson存在于类路径中 Web Flux 通过 compile 'org.springframework:spring-context:5.0.2.RELEASE' compile 'org.springframework:spring-web:5.0.2.RELEASE' compile 'org.springframework:spring-webflux:5.0.2.RELEASE' compile 'io.projectreactor.ipc:reactor-netty:0.7.2.RELEASE' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.3' 自动创建一个Object Mapper实例但是它不清楚如何覆盖对象映射器实例,因为大多数 Web Flux < / em>配置类是包私有。

我想要实现的是创建自己的对象映射器,以添加jackson-modules-java8 中实现的自定义Mono<>序列化

DefaultServerCodecConfigurer

问题在于,不清楚如何修改在私有LocalDateTime包中创建的ObjectMapper mapper = new ObjectMapper() .registerModule(new ParameterNamesModule()) .registerModule(new Jdk8Module()) .registerModule(new JavaTimeModule()) ;

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容从application.properties文件中停用该功能:

spring.jackson.serialization.write-dates-as-timestamps=false

答案 1 :(得分:0)

事实证明,最初比我想象的更简单,因为DelegatingWebFluxConfiguration已经有configureHttpMessageCodecs方法覆盖哪个就够了

@Configuration
public class EmbeddedSpringServer extends DelegatingWebFluxConfiguration {
    @Bean
    MyController controller() {
        return new MyController();
    }

    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EmbeddedSpringServer.class);
        HttpHandler handler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
        ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
        HttpServer.create("0.0.0.0", 8082).newHandler(adapter).subscribe();
        applicationContext.registerShutdownHook();
    }

    @Bean
    ObjectMapper objectMapper(){
        return new ObjectMapper()
                .registerModule(new ParameterNamesModule())
                .registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule());

    }

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

至于Spring Boot我认为也可以通过返回webFluxConfigurer bean来实现

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

DelegatingWebFluxConfiguration自动创建的@EnableWebFlux选择

<强> N.B。 Jackson2ObjectMapperBuilder的默认实现已经自动注册这些日期模块与日期无关的问题,我结束了

@Override
    protected void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(Jackson2ObjectMapperBuilder
        .json()
          .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
        .build()));
    } 

实现简单的日期序列化。