2017-03-17 35 views
3

使用Spring引導1.4.4.RELEASE,保存一個RequestBody到的MongoDB如下:反序列化MongoDB的日期字段到Java POJO使用傑克遜

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

雖然這個映射回一個Java POJO,我想的下面的代碼。

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

連載已日期字段返回如下

"startDate" : { "$date" : "2017-01-04T15:15:55.570Z"} 

由於$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"])} 

有沒有辦法解決這個問題,而無需使用ODM?

回答

2

當反序列化到Date Jackson預計String"2017-01-04T15:15:55.570Z"。相反,它看到JSON內的另一個對象({ char)的開始,因此是例外。

考慮指定您的Pojo類和其他類MongoDate與此類似:

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

class Pojo { 
    long startTime; 
    long endTime; 
    MongoDate startDate; 
    MongoDate endDate; 
} 

另外,如果你不能/不想添加MongoDate類,你可以引入一個自定義解串器Date領域。在這種情況下Pojo

class Pojo { 
    long startTime; 
    long endTime; 
    @JsonDeserialize(using = MongoDateConverter.class) 
    Date startDate; 
    @JsonDeserialize(using = MongoDateConverter.class) 
    Date endDate; 
} 

和解串器應該是這樣的:

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; 
     } 
    } 
} 
+0

但是這需要對Java數據結構進行更改。不會是一個定製的傑克遜(德)序列化器更好的解決方案? – Robert

-1

我回去,並嘗試過類似使用解串器的方法。

下面的代碼:

public class MongoDateDeserializer extends JsonDeserializer<Date> { 

@Override 
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 
     throws IOException { 
    ObjectCodec oc = jsonParser.getCodec(); 
    JsonNode node = oc.readTree(jsonParser); 
    String dateValue = node.get("$date") 
          .asText(); 
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 
    Date date = null; 
    try { 
     date = df.parse(dateValue); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 
    return date; 
}} 

變化VO的情況如下:

@JsonDeserialize(using = MongoDateDeserializer.class) 
private Date startDate; 

@JsonDeserialize(using = MongoDateDeserializer.class) 
private Date endDate; 

這很順利。 但是,如果MongoDB的JSON.serialize執行返回規範化json的工作,那會更好。希望將來。