2

目前我有一个带有 Jackson 库的简约Spring / NettyReactor / Web Flux项目

@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();
    }
}

构建.gradle:

        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'

控制器类工作正常(它返回Mono<>一个 DTO 类型)。因为 Jackson 存在于类路径中,所以Web Flux会自动创建一个 Object Mapper 实例,DefaultServerCodecConfigurer但是不清楚如何覆盖对象映射器实例,因为大多数Web Flux配置类都是包私有的。

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

ObjectMapper mapper = new ObjectMapper()
   .registerModule(new ParameterNamesModule())
   .registerModule(new Jdk8Module())
   .registerModule(new JavaTimeModule())
;

问题是不清楚如何修改Jackson2JsonEncoder在包 private 中创建的org.springframework.http.codec.support.AbstractCodecConfigurer.AbstractDefaultCodecs

4

2 回答 2

1

结果比我最初想象的要简单,因为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

NB的默认实现Jackson2ObjectMapperBuilder已经自动注册了这些日期模块与日期的问题无关,我以

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

实现简单的日期序列化。

于 2017-12-21T13:02:33.710 回答
1

您可以直接从您的application.properties文件中禁用该杰克逊功能:

spring.jackson.serialization.write-dates-as-timestamps=false
于 2017-12-21T15:38:45.667 回答