Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring Boot中为Camel配置Jackson ObjectMapper_Java_Spring Boot_Jackson_Apache Camel - Fatal编程技术网

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

Java 如何在Spring Boot中为Camel配置Jackson ObjectMapper,java,spring-boot,jackson,apache-camel,Java,Spring Boot,Jackson,Apache Camel,我正在尝试使用Jackson在驼峰路由上序列化和反序列化POJO与JSON之间的通信。其中一些具有Java8LocalDate字段,我希望将它们序列化为YYYY-MM-DD字符串,而不是整数数组 我们的Spring Boot应用程序只使用Java配置,所以没有XML配置 我已经成功创建了一个ObjectMapper,它可以满足我的需要,通过将其添加到依赖项中,我们系统的其他部分正在使用它: <dependency> <groupId>com.fasterxml.j

我正在尝试使用Jackson在驼峰路由上序列化和反序列化POJO与JSON之间的通信。其中一些具有Java8LocalDate字段,我希望将它们序列化为YYYY-MM-DD字符串,而不是整数数组

我们的Spring Boot应用程序只使用Java配置,所以没有XML配置

我已经成功创建了一个ObjectMapper,它可以满足我的需要,通过将其添加到依赖项中,我们系统的其他部分正在使用它:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.6.1</version>
</dependency>
出站休息路线示例:

@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序列化程序/反序列化程序,也不会使用禁用的时间戳功能。我已经阅读了文档,但它没有显示如何使用Spring配置添加自定义数据格式,或者如何对所有类型应用全局自定义


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

在Java代码中创建
JacksonDataFormat
,并启用/禁用所需的功能,然后在Camel路由中使用该实例

 .unmarshal(myInstanceGoesHere).

如果Camel给您带来麻烦,我将恢复直接使用bean:

  • 只需创建一个小型Json实用程序,它可以进行编组和解编组,并将预配置的ObjectMapper自动连接到其中

  • 利用Camels Asomes Spring bean集成调用您的实用程序并在路由中转换消息,例如:

         from(uri)
            .unmarshal().json(JsonLibrary.Jackson)
            .beanRef("jsonUtil", "unmarshal")
            .bean(myBean);
    

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

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

    @Bean(name = "json-jackson")
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public JacksonDataFormat jacksonDataFormat(ObjectMapper objectMapper) {
        return new JacksonDataFormat(objectMapper, HashMap.class);
    }
    
    需要注意的要点:

    • JacksonDataFormat
      的构造函数没有接受不带解组器类型的
      ObjectMapper
      。但是,在默认构造函数中,如果没有提供解组类型,则使用
      HashMap.class
      ,因此我使用它。通过某种神奇的方式,这似乎已经习惯于解组所有POJO类型。如果您还需要其他类的更具体的数据格式,则还需要在这些类中设置
      ObjectMapper
    • Camel似乎在bean注册表中搜索一个名为“json jackson”的bean,因此将springbean设置为使用该名称会诱使Camel不创建新名称,而是使用我的名称
    • bean范围必须设置为
      scope\u PROTOTYPE
      ,因为REST DSL希望获得
      DataFormat
      的新实例。看

    使用Spring和Camel 2.18.1,我通过添加以下依赖项实现了相同的功能:

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-parameter-names</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jdk8</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>2.6.1</version>
    </dependency>
    

    到目前为止,只有戴维·爱德华兹的建议对我有效。我首先定义了一个id为“json jackson”的数据格式bean

    
    
    然后是format类:

    公共类JacksonDataFormat扩展了JacksonDataFormat{
    公共JacksonDataFormatExt(){
    超级();
    setPrettyPrint(真);
    setEnableFeatures(SerializationFeature.WRITE_DATES_为_TIMESTAMPS.name());
    SimpleModule s=新的SimpleModule();
    s、 addSerializer(CustomEnum.class,新的CustomEnumSerializer());
    添加模块;
    }
    }
    
    和CustomEnumSerializer类:

    公共类CustomEnumSerializer扩展JsonSerializer{
    @凌驾
    public void serialize(CustomEnumvalue、JsonGenerator jgen、SerializerProvider提供程序)引发IOException、JsonProcessingException{
    字符串stringValue=value.getNlsText();
    if(stringValue!=null&&!stringValue.isEmpty()&&!stringValue.equals(“null”)){
    jgen.writeString(stringValue);
    }否则{
    jgen.writeNull();
    }
    }
    }
    
    我使用
    org.apache.Camel:Camel-jackson-starter:2.20.0

    它通过Spring应用程序属性为配置公开了一些有用的ObjectMapper属性。例如,可以直接从application.yaml或application.properties文件将日期写入时间戳

    有关更多详细信息,请查看JacksonDataFormatConfiguration类

    我还需要使用一些mixin,所以我仍然需要将Camel配置为使用Spring的ObjectMapper。我的结局是:

    配置bean:

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return new Jackson2ObjectMapperBuilderCustomizer() {
            @Override
            public void customize(Jackson2ObjectMapperBuilder builder) {
                builder.mixIn(Person.class, PersonMixin.class);
            }
        }
    }
    
    application.yaml:

    camel:
      dataformat:
        json-jackson:
          disable-features: WRITE_DATES_AS_TIMESTAMPS
          object-mapper: jacksonObjectMapper
    

    其中,
    jacksonObjectMapper
    是由已配置的Jackson2ObjectMapperBuilder构建的ObjectMapper bean的名称

    我无法让任何示例工作。有点失望的是,从阅读变通办法来看,这相当复杂

    在我看来,camel应该通过使用应用程序附带的同一个jacksonbean来简化Spring默认对象映射器的使用

    我放弃了使用
    .json()
    ,而将其替换为处理器

    与下面一样,它使用了Spring提供的objectMapper

    路线

    from(CONSUME_TAG)
     .process("jsonProcessor")
     .to("direct:anotherRoute")
     .end();
    
    通用处理器注意这是如何自动连接spring boot objectMapper bean的

    @Component
    public class JsonProcessor implements Processor {
    
        @Autowired
        ObjectMapper objectMapper;
    
        @Override
        public void process(Exchange exchange) throws Exception {
            exchange.getOut().setBody(objectMapper.writeValueAsString(exchange.getIn().getBody()));
        }
    
    }
    

    如果有人想知道如何使用安装在版本中的修复程序。2.17.. 我使用以下xml配置使其正常工作:

    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        return builder
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .build();
    }
    
     <camel:camelContext id="defaultCamelContext">
           .....
            <camel:dataFormats>
                <camel:json id="json" library="Jackson"  objectMapper="myObjectMapper"/>
            </camel:dataFormats>
    
     </camel:camelContext>
    
    
    .....
    

    …其中myObjectMapper是ObjectMapper类型的spring bean的名称

    I通过在pom中包含jackson依赖项来解决

    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-jackson-starter</artifactId>
      <version>${camel.version}</version>
    </dependency>
    

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

    camel.dataformat.json-jackson.auto-discover-object-mapper=true
    
    如果设置为true,则Jackson将在注册表中查找objectMapper

    文件:

    日志:

    (警告仅表示,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