spring boot Joda DateTime 序列化

Posted

技术标签:

【中文标题】spring boot Joda DateTime 序列化【英文标题】:spring boot Joda DateTime Serialisation 【发布时间】:2015-01-11 15:01:22 【问题描述】:

我正在尝试使用 Spring Boot v1.2.0.BUILD-SNAPSHOT 将 Joda DateTime 属性序列化为 ISO-8601 这是我非常简单的 REST 应用程序。

@RestController
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application 

    class Info

       private DateTime dateTime;

        public Info()
            dateTime = new DateTime();
        
        public DateTime getDateTime() 
           return dateTime;
        

        public void setDateTime(DateTime dateTime) 
           this.dateTime = dateTime;
        
    

    @RequestMapping("/info")
    Info info() 
        return new Info();
    

    public static void main(String[] args) 
        SpringApplication.run(Application.class, args);
    

    @Bean
   public Module getModule()
        return new JodaModule();
   

dateTime 被序列化为时间戳,例如"dateTime":1415954873412 我试过添加

@Bean
@Primary
public ObjectMapper getObjectMapper() 
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                false);
    return objectMapper;

但这也无济于事。那么如何在 Spring Boot 中配置 Jackson 以使用 ISO-8601 格式进行序列化呢? 顺便说一句:我只在我的 Gradle 构建中添加了以下依赖项

compile("joda-time:joda-time:2.4")
compile("org.jadira.usertype:usertype.jodatime:2.0.1")
compile("com.fasterxml.jackson.datatype:jackson-datatype-joda:2.4.2");

【问题讨论】:

【参考方案1】:

还有一个 joda-date-time-format 属性(我认为这个属性第一次出现在 Spring boot 1.3.x 版本中)你可以在你的 application.properties 中设置它适用于 jackson 序列化/反序列化:

发件人:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

spring.jackson.joda-date-time-format= # Joda date time format string. If not configured, "date-format" will be used as a fallback if it is configured with a format string.

所以如果你想使用 ISO 格式你可以这样设置:

spring.jackson.joda-date-time-format=yyyy-MM-dd'T'HH:mm:ss.SSSZ

您可以使用不同数量的“Z”来更改时区 ID 或偏移小时数的显示方式,来自 joda 时间文档 (http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html):

Zone: 'Z' outputs offset without a colon, 'ZZ' outputs the offset with a colon, 'ZZZ' or more outputs the zone id.

【讨论】:

【参考方案2】:

将此添加到您资源中的application.*。 (我使用 yamel,所以它对我来说是 .yml,但默认情况下应该是 .properties

spring.jackson.date-format: yyyy-MM-dd'T'HH:mm:ssZ

或者你想要的任何格式。

【讨论】:

【参考方案3】:

使用 Spring Boot 1.2,您可以使用流畅的 builder 构建 ObjectMapper 实例:

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

至于JodaModule,当com.fasterxml.jackson.datatype:jackson-datatype-joda在类路径上时会自动配置。

【讨论】:

【参考方案4】:

由于您使用的是 Spring Boot 1.2,您应该能够简单地将以下内容添加到您的 application.properties 文件中:

spring.jackson.serialization.write_dates_as_timestamps=false

这将以以下形式给出输出:


    "dateTime": "2014-11-18T19:01:38.352Z"

如果您需要自定义格式,您可以直接配置JodaModule,例如删除时间部分:

@Bean
public JodaModule jacksonJodaModule() 
    JodaModule module = new JodaModule();
    DateTimeFormatterFactory formatterFactory = new DateTimeFormatterFactory();
    formatterFactory.setIso(ISO.DATE);
    module.addSerializer(DateTime.class, new DateTimeSerializer(
        new JacksonJodaFormat(formatterFactory.createDateTimeFormatter()
            .withZoneUTC())));
    return module;

【讨论】:

我已经尝试了以下每个都没有成功 1.将其添加到 application.properties 文件 spring.jackson.serialization.write_dates_as_timestamps=false 2.如下创建一个 bean @Bean public Module getModule() 返回新的 JodaModule(); 3. 自动装配 ObjectMapper 并设置 objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);唯一有效的方法是注释属性 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ") 为我工作。我已经将我的示例推送到 GitHub github.com/philwebb/***-26926289 谢谢你 - 我让它工作了。我正在使用 compile("org.springframework.boot:spring-boot-starter-data-rest") 但它适用于: compile("org.springframework.boot:spring-boot-starter-web") 这是一个错误还是一个功能? :) 并不是说你也会在你的 pom 中看到工件 jackson-datatype-joda 很高兴您在 GitHub @PhilWebb 上发布了示例代码。帮助我意识到我在尝试序列化的类中必须使用 org.joda.time.DateTime 而不是 java.util.Date ......以使此配置正常工作。 (值得注意的是,Swagger 代码自动生成 - 针对 Spring - 使用 java.util.Date 而不是 joda DateTime 类)。 更新 实际上并不积极我已经想通了,但是嘿。以为我会分享,以防它是图片的一部分。【参考方案5】:

new JodaModule() 传递给对象映射器的构造函数。

使用 ISO 模式注释您的 Info 方法

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")

或者我认为如果您使用的是 spring,您可以使用它

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateTimeFormat.ISO.DATE_TIME)

【讨论】:

你也可以调用 .setSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");在您的对象映射器上而不是注释类。 唯一有效的是如果我使用注释,即@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" ) 必须有某种方法可以启用所有 DateTime 属性。我不想注释所有的属性 不确定是否有帮助,但可能值得升级到最新版本 2.4.3。另外:如果@JsonFormat 覆盖有效,但SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 无效,我会针对该模块提交一个错误——它应该按您期望的方式工作。 2.4.3 没有帮助。我尝试了几种方法,但注意工作。我的印象是 SpringBoot 使用的 ObjectMapper 实例与我尝试配置的实例不同。这对我来说似乎是一个错误,但我在几个线程中读到这应该只是添加 JodaModule 的一个案例 根据文档(§63.3 Customize the Jackson ObjectMapper)应该可以配置 application.properties spring.jackson.serialization.write_dates_as_timestamps=false

以上是关于spring boot Joda DateTime 序列化的主要内容,如果未能解决你的问题,请参考以下文章

自从升级到 spring boot 1.4 / spring cloud camden 以来,BeanPropertyRowMapper 不再理解 joda 时间类型

如何将 Joda Localdate 转换为 Joda DateTime?

如何从 org.joda.time.DateTime 转换为 java.time.ZonedDateTime

将带有joda.DateTime的案例类的DStream转换为Spark DataFrame

Joda DateTime 到 BigDecimal 分数计算

org.joda.time.DateTime 日期格式