【问题标题】:Spring Integration Transformer: Serialize LocalDateTime to Json as ISO StringSpring Integration Transformer:将 LocalDateTime 序列化为 Json 作为 ISO 字符串
【发布时间】:2022-11-29 02:37:27
【问题描述】:

使用 Spring Integration,我需要将对象从外部 API 包转换为 JSON,最后通过 AmqpOutboundEndpoint 发送它。为此,我使用 ObjectToJsonTransformer。

问题在于该类的 LocalDateTime 属性:它们被序列化为整数数组 [yyyy,mm,dd,HH,MM,ss],但我希望将它们转换为 ISO 8601 日期时间字符串。

我看到这个问题很常见,到目前为止我已经将 jackson-datatype-jsr310 添加到依赖项并设置属性spring.jackson.serialization.write_data_as_timestamps: true,但这没有帮助。

请给我一个可行解决方案的提示。

编辑:添加源代码(删除包和导入行)和 pom.xml:

@Configuration
@EnableAutoConfiguration
@IntegrationComponentScan
public class Application {

    public static void main(String[] args) throws InterruptedException {
        ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);

        List<Data> source = Arrays.asList(new Data());
        ctx.getBean(Demo.class).demo(source);

        ctx.close();
    }

    @MessagingGateway
    public interface Demo {

        @Gateway(requestChannel = "upcase.input")
        void demo(Collection<Data> source);

    }

    public static class Data {

        public LocalDateTime getLocalDateTime() {
            return LocalDateTime.now();
        }

    }

    @Bean
    public IntegrationFlow upcase() {
        return f -> f
                .split()
                .log()
                .transform(new ObjectToJsonTransformer())
                .log()
                .handle(m -> System.out.printf("%n%s%n%n", m.getPayload()));
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <spring.integration>5.5.15</spring.integration>
        <java.version>11</java.version>
    </properties>
    <groupId>com.example</groupId>
    <artifactId>spring-int</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-int</name>
    <description>Demo project for Spring Boot</description>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

【问题讨论】:

  • 好吧,据我所知添加 jackson-datatype-jsr310 应该就足够了。 ObjectToJsonTransformer 会自动配置相应的模块,WRITE_DATES_AS_TIMESTAMPS(true) 无论如何都是默认的。您有没有机会与我们分享一个简单的项目来重现和玩耍?
  • @ArtemBilan 感谢您的反馈,我添加了示例代码和 pom.xml。运行示例代码的输出为:{"localDateTime":[2022,11,28,18,20,31,599393100]}(当然打印的是当前本地时间)

标签: java jackson spring-integration


【解决方案1】:

我认为你的期望恰恰相反。

LocalDateTimeSerializer 的逻辑如下:

   if (useTimestamp(provider)) {
        g.writeStartArray();
        _serializeAsArrayContents(value, g, provider);
        g.writeEndArray();
    }

因此,对于 spring.jackson.serialization.write-dates-as-timestamps=true(默认情况下),我们确实将拥有一组 LocalDateTime 属性。

如果你谈论 ISO 8601 的格式,那么你需要做完全相反的事情:spring.jackson.serialization.write-dates-as-timestamps=false。而这个配置修改:

public IntegrationFlow upcase(ObjectMapper objectMapper) {
  ...
  .transform(new ObjectToJsonTransformer(new Jackson2JsonObjectMapper(objectMapper)))

能够采用正确的自动配置ObjectMapper

提到的 LocalDateTimeSerializer 将通过其进行 LocalDateTime 格式化:

protected DateTimeFormatter _defaultFormatter() {
    return DateTimeFormatter.ISO_LOCAL_DATE_TIME;
}

使用此配置,我得到如下输出:

{"localDateTime":"2022-11-28T13:17:30.4691295"}

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 2018-07-24
    • 2012-01-09
    • 2012-08-15
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多