使用Jackson将MongoDB日期字段反序列化为Java POJO

muk*_*rma 6 java spring json mongodb jackson

使用Spring Boot 1.4.4.RELEASE,已将一个保存RequestBody到MongoDB,如下所示:

{
    "startTime" : NumberLong("1483542955570"),
    "startDate" : ISODate("2017-01-04T15:15:55.570Z"),
    "endTime" : NumberLong("1483542955570"),
    "endDate" : ISODate("2017-01-04T15:15:55.570Z")
}
Run Code Online (Sandbox Code Playgroud)

在将其映射回Java POJO时,我正在尝试以下代码.

public <T> T getPOJOFromMongoDocument(Document resourceDocument, Class<T> clazz) {
        String serialize = JSON.serialize(resourceDocument);
        return objectMapper.readValue(serialize,
                                      clazz);
}
Run Code Online (Sandbox Code Playgroud)

serialize具有如下返回的日期字段

"startDate" : { "$date" : "2017-01-04T15:15:55.570Z"}
Run Code Online (Sandbox Code Playgroud)

由于$date,杰克逊ObjectMapper在解析期间返回以下异常:

java.lang.RuntimeException: Error parsing mongoDoc to Pojo : errorMessage : {Can not deserialize instance of java.util.Date out of START_OBJECT token at [Source: {
"startTime": 1483542955570,
"startDate": {
    "$date": "2017-01-04T15:15:55.570Z"
},
"endTime": 1483542955570,
"endDate": {
    "$date": "2017-01-04T15:15:55.570Z"
}}; line: 1, column: 381] (through reference chain: com.gofynd.engine.mongo.models.RuleWithDataVO["validity"]->com.gofynd.engine.mongo.models.ValidityVO["startDate"])}
Run Code Online (Sandbox Code Playgroud)

有没有办法解决这个问题而不使用ODM?

Man*_*dis 7

反序列化时,Date杰克逊期望会String喜欢"2017-01-04T15:15:55.570Z"。相反,它看到{JSON 中另一个对象(字符)的开始,因此是异常。

考虑指定您的Pojo班级和另一个MongoDate与此类似的班级:

class MongoDate {
    @JsonProperty("$date")
    Date date;
}

class Pojo {
    long startTime;
    long endTime;
    MongoDate startDate;
    MongoDate endDate;
}
Run Code Online (Sandbox Code Playgroud)

另外,如果您不能/不想添加MongoDate类,则可以为Date字段引入自定义反序列化器。在这种情况下Pojo

class Pojo {
    long startTime;
    long endTime;
    @JsonDeserialize(using = MongoDateConverter.class)
    Date startDate;
    @JsonDeserialize(using = MongoDateConverter.class)
    Date endDate;
}
Run Code Online (Sandbox Code Playgroud)

解串器如下所示:

class MongoDateConverter extends JsonDeserializer<Date> {
    private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        JsonNode node = jp.readValueAsTree();
        try {
            return formatter.parse(node.get("$date").asText());
        } catch (ParseException e) {
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)