如何在 Spring Boot 中为 Camel 配置 Jackson ObjectMapper

2022-09-01 20:48:37

我正在尝试使用Jackson在Camel路由上序列化和反序列化POJO和反序列化。其中一些具有Java 8 LocalDate字段,我希望它们被序列化为YYYY-MM-DD字符串,而不是整数数组。

我们只对Spring Boot应用程序使用Java配置,因此没有XML Camel配置。

我已经成功地创建了一个ObjectMapper,它可以做我想要的事情,通过将其添加到我们的依赖项中,它被我们系统的其他部分使用:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

以及我们的应用程序配置:

@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    return builder
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build();
}

传出 REST 路由示例:

@Component
public class MyRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        restConfiguration().component("servlet").contextPath("/mycontext")
                .port(8080).bindingMode(RestBindingMode.json);

        rest("/myendpoint)
                .get()
                .route()
                .to("bean:myService?method=myMethod()");
    }
}

传入消息路由示例:

@Component
public class MyRouteBuilder extends RouteBuilder {

    @Autowired
    private MyBean myBean;

    @Override
    public void configure() {
        from(uri)
                .unmarshal().json(JsonLibrary.Jackson)
                .bean(myBean);
    }
}

但是,默认情况下,Camel 会创建自己的 ObjectMapper 实例,因此不会选择自动添加的 JSR310 序列化程序/反序列化程序或禁用的功能。我已经阅读了Camel JSON文档,但它没有说明如何使用Spring配置添加自定义DataFormat,或者如何为所有类型应用全局自定义。Jackson2ObjectMapperBuilderWRITE_DATES_AS_TIMESTAMPS

那么,我该如何告诉 Camel 只使用 Spring Boot Java 配置来使用我的 ObjectMapper 呢?


答案 1

我通过逐步执行Camel代码找到了解决方案。因此,虽然它做了我想要的,但它可能无法与Camel的未来版本一起使用,因为它似乎没有文档记录并且可能不受支持。

我所要做的就是将以下bean添加到我的Spring配置中,除了我在问题中的bean之外:ObjectMapper

@Bean(name = "json-jackson")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public JacksonDataFormat jacksonDataFormat(ObjectMapper objectMapper) {
    return new JacksonDataFormat(objectMapper, HashMap.class);
}

需要注意的关键点:

  • 没有构造函数,因为它需要一个没有非元帅的类型。但是,在默认构造函数中,当未提供非元帅类型时,将使用 a,因此我使用它。通过一些魔法,这似乎习惯了所有POJO类型的解体。如果还需要为其他类设置更具体的数据格式,则还需要在其中设置 。JacksonDataFormatObjectMapperHashMap.classObjectMapper
  • 骆驼似乎在豆子注册表中搜索一种名为“json-jackson”的豆子,因此将Spring bean设置为使用该名称会欺骗Camel不创建新豆并使用我的豆子。
  • 必须将 Bean 作用域设置为,因为 REST DSL 期望获取 的新实例。参见骆驼-7880SCOPE_PROTOTYPEDataFormat

答案 2

大家好消息,现在Spring Boot支持对象映射器自动发现!只需设置此属性:

camel.dataformat.json-jackson.auto-discover-object-mapper=true

如果设置为 true,则 Jackson 将在注册表中查找对象映射器

文档: https://camel.apache.org/components/latest/dataformats/json-jackson-dataformat.html#_spring_boot_auto_configuration

原木:

INFO o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 3.3.0 (CamelContext: camel-1) is starting
INFO o.a.c.c.jackson.JacksonDataFormat        : Found single ObjectMapper in Registry to use: com.fasterxml.jackson.databind.ObjectMapper@20a1b3ae
WARN o.a.c.c.jackson.JacksonDataFormat        : The objectMapper was already found in the registry, no customizations will be applied

(警告只是表示,您的所有其他属性都将被忽略)camel.dataformat.json-jackson.*

更新 17.08.2022

对于新版本的骆驼,因为使用不同的属性3.15.0

camel.dataformat.jackson.auto-discover-object-mapper=true

推荐