当前位置: 首页 > 知识库问答 >
问题:

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

令狐昌胤
2023-03-14

目前,我与Jackson libraries有一个极简的Spring/Netty、Reactor/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();
    }
}
        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'

Controller类工作良好(它返回具有DTO类型的mono<>)。由于Jackson存在于类路径中,Web Flux通过DefaultServerCodeCconfigureer自动创建对象映射器实例,但不清楚如何覆盖对象映射器实例,因为大多数Web Flux配置类都是包专用的。

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

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

问题是,不清楚如何修改包privateorg.springframework.http.codec.support.abstractcodecconfigurer.abstractdefaultcodecs中创建的jackson2jsonencoder

共有1个答案

公孙联
2023-03-14

结果比我最初想象的要简单,因为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引导,我认为也可以通过返回WebFluxConfigureer 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());
            }
        };
    }

因为它们是由@enablewebflux自动创建的delegatingwebfluxconfiguration选择的。

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

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

以实现简单的日期序列化。

 类似资料:
  • 问题内容: 我正在尝试使用Swift协议扩展,却发现这种行为令人困惑。您能帮我得到我想要的结果吗? 请参阅代码最后4行的注释。(如果需要,可以将其复制粘贴到Xcode7游乐场)。谢谢!! 问题答案: 简短的答案是协议扩展不执行类多态性。这是有一定道理的,因为协议可以被结构或枚举采用,并且因为我们不希望仅在没有必要的地方采用协议来引入动态调度。 因此,在中,实例变量(可能更准确地写为)并不意味着您认

  • 问题内容: 如果我上课: 我最初以为我可以通过添加扩展名来覆盖子类而无需子类化: 该代码不会编译,但错误说明了该函数,这很有意义。 我的问题是: 是否仍要重写特定类的功能?换句话说,在某些情况下,例如上面的示例中,我可以替换功能吗?如果没有,是否有其他解决方法或方法来实现该行为(可能声明了另一个协议,idk) 现在,我考虑得更多了,我不得不说这是不可能的,因为是什么阻止某人重写任何标准库函数? 问

  • 问题内容: 我想在我的JS代码中扔一些东西,我希望它们是Error的instanceof,但我也想让它们成为其他东西。 在Python中,通常将Exception子类化。 在JS中适合做些什么? 问题答案: 在ES6中:

  • 问题内容: 对于每个中间件,Express都传递一个和一个对象。这些对象扩展了分别来自和的本地对象。我想知道是否有可能覆盖或扩展响应对象的方法。 例如,而不是,我想延长一个名为customRender一个自定义的方法,并使用它像这样:。 我没有遇到任何特定问题或其他任何问题。我只是想学习如何扩展本机对象,或者像本例一样,扩展来自Node.js中第三者模块的对象 问题答案: 最好的主意是在响应对象的

  • 问题内容: 是否可以将扩展方法添加到python内置类型中?我知道我可以通过简单地通过添加新方法来将扩展方法添加到定义的类型。如下: 但是是将扩展方法添加到python内置类型(如列表,字典,…)的任何方法 问题答案: 可以使用以下非常聪明的模块在纯Python中完成此操作: https://pypi.python.org/pypi/forbiddenfruit 例如: 在那里,感觉不舒服吗?

  • 我正在使用findByIdAndUpdate更新修改的表单字段。 它是否覆盖了文档中甚至未在表单中修改的所有字段?