【问题标题】:Serializing Joda DateTime with Jackson and Spring使用 Jackson 和 Spring 序列化 Joda DateTime
【发布时间】:2015-06-20 14:57:26
【问题描述】:

我一直在使用 Spring Boot 和 Jackson-databind 2.5.2 将 Joda DateTime 从 java 序列化和反序列化到 json 并再次返回时遇到问题。我的 pom.xml 是这样的。

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.2</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-joda</artifactId>
    <version>2.5.2</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.2.1.RELEASE</version>
</dependency>

当我序列化 DateTime 对象时,我得到一个表示 DateTime 的整数。实际上不是我所期望的,但很好。但是当我去保存我的对象时,我得到了以下错误......

Failed to convert property value of type 'java.lang.String' to required type 'org.joda.time.DateTime' for property 'endTime';
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type org.joda.time.DateTime for value '1428600998511'

出于某种原因,它会将其序列化为整数,然后将其反序列化,就好像它是一个字符串一样,但事实并非如此。我还尝试在调用其余服务之前设置 endTime = new Date(intValue) 并且尝试将像 'Tue Apr 28 2015 00:00:00 GMT-0700 (PDT)' 这样的字符串转换为 DateTime 也失败了。

我做错了什么?

更新:

这是我得到的 JSON,我尝试立即回帖。

{
    id: 4,
    username: "",
    name: "eau",
    email: "aoue",
    verbatimLocation: null,
    latitude: null,
    longitude: null,
    startTime:null,
    endTime: 1429034332312,
    description: "ueoa",
    media: [ ],
    timeSubmitted: 1428600998000,
    status: null,
    submissionid: null
}

【问题讨论】:

  • 你能发布一些相关的 JSON,进出吗?看起来将 JSON 发布回您的控制器的任何内容都将您的日期作为字符串发布。
  • 也许您需要用@JsonFormat 注释该字段?例如@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
  • 好吧,这似乎成功了!谢谢!最后我只是回到存储我的日期,只要在 javascript 端,我使用的工具不能很好地处理我在 Java 端使用它们的相同格式的日期。这太令人沮丧了。

标签: jackson spring-boot jodatime


【解决方案1】:

对于更可重用的机制,您可以创建一个JsonSerializer

/**
 * When passing JSON around, it's good to use a standard text representation of
 * the date, rather than the full details of a Joda DateTime object. Therefore,
 * this will serialize the value to the ISO-8601 standard:
 * <pre>yyyy-MM-dd'T'HH:mm:ss.SSSZ</pre>
 * This can then be parsed by a JavaScript library such as moment.js.
 */
public class JsonJodaDateTimeSerializer extends JsonSerializer<DateTime> {

    private static DateTimeFormatter formatter = ISODateTimeFormat.dateTime();

    @Override
    public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2)
            throws IOException, JsonProcessingException {

        gen.writeString(formatter.print(value));
    }

}

然后你可以注释你的 get 方法:

@JsonSerialize(using = JsonJodaDateTimeSerializer.class)

这为您在整个应用程序中提供一致的格式,而无需到处重复文本模式。它还可以识别时区。

【讨论】:

  • 如何反序列化这个?
  • 还有一个@JsonDeserialize注解。
【解决方案2】:

最后我能够按照beerbajay 所说的那样使用......

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

... 序列化我的日期。不过,我最终还是使用 Long 而不是 DateTime,因为在 javascript 端处理日期太麻烦了。事实证明,找到一个适用于 jquery datepicker、joda DateTime 和 postgresql 的模式对于我仅有的一点时间来说工作量太大了。

【讨论】:

  • 您是如何解决最初的问题的?
  • 顺便说一句,如果你想要一个特定的格式,并在任何地方使用它作为日期,你可以在 application.properties 中指定这个spring.jackson.date-formatdocs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/…
  • 好吧,我没有绕过它。最后,我只是暂时将我的日期存储在数据库中。当我有更多时间时,我可能会考虑使用 moment.js 或其他可以处理更复杂字符串格式的日期实用程序。
猜你喜欢
  • 1970-01-01
  • 2015-01-11
  • 2014-10-13
  • 2011-08-07
  • 2014-11-13
  • 2013-09-25
  • 2011-03-17
  • 2014-02-16
  • 2018-03-14
相关资源
最近更新 更多