2017-03-17 107 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的工作,那会更好。希望将来。