gpt4 book ai didi

java - 来自 MongoDB BSON 的 Jackson ObjectMapper

转载 作者:可可西里 更新时间:2023-11-01 10:45:13 24 4
gpt4 key购买 nike

我得到了一个 JSON,我将其序列化为 MongoDB BasicDBObject 并将其插入到数据库中:

    String serialized = "";
try {
serialized = OBJECT_MAPPER.writeValueAsString(customEx.getOut().getBody());
} catch (JsonProcessingException e) {
e.printStackTrace();
}

collection.update(upsertQuery, BasicDBObject.parse(serialized), true, false);

在从数据库中读取 DBObject 时,我想使用带有给定类的 ObjectMappers' readValue() 将其转换为 POJO :

    public static <T> T fromDB(DBObject o, Class<T> clazz) {
try {
return OBJECT_MAPPER.readValue(o.toString(), clazz);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

我想将其转换成的类是从 xsd sheme 生成的,还包含如下所示的 timestamps/long 值:

@XmlRootElement(name = "ItemType")
public class ItemType {

@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar date;
[...]

然而,这对于较旧的 Java MongoDB 版本来说效果很好。现在长值被序列化为 BSON,如下所示:

"date": {
"$numberLong": "1551172199214"
}

当我尝试使用 jacksons ObjectMapper 反序列化它时,我得到了

Cannot deserialize instance of javax.xml.datatype.XMLGregorianCalendar out of START_OBJECT token

我很清楚这样做的原因,因为 long 值在自己的 BSON - Style 对象中。

到目前为止,我已经尝试过像这样使用 BsonDocument:

public static <T> T fromDB(DBObject o, Class<T> clazz) {
try {
BsonDocument parse = BsonDocument.parse(o.toString());
return OBJECT_MAPPER.readValue(parse.toJson(), clazz);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

但这仍然没有将 BSON 部分转换为 JSON。

有没有办法使用 Jacksons ObjectMapper 将 BSON 反序列化为给定的类?或者只是将它转换为 DBObject 而不使用 BSON 部件?

最佳答案

如果日历字段被包装,我们需要将其解包。我们可以扩展已经实现的 CoreXMLDeserializers.GregorianCalendarDeserializer:

class XmlGregorianCalendarDeserializer extends CoreXMLDeserializers.GregorianCalendarDeserializer {

@Override
public XMLGregorianCalendar deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
jp.nextToken(); // Skip FIELD_NAME
jp.nextToken(); // Skip VALUE_STRING

XMLGregorianCalendar calendar = super.deserialize(jp, ctxt);

jp.nextToken(); // Skip END_OBJECT

return calendar;
}
}

如果 XMLGregorianCalendar 总是被包装,我们可以使用 SimpleModule 注册这个反序列化器。请参见以下示例:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ext.CoreXMLDeserializers;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import javax.xml.datatype.XMLGregorianCalendar;

public class Test {

public static void main(String[] args) throws Exception {
SimpleModule wrappedCalendarModule = new SimpleModule();
wrappedCalendarModule.addDeserializer(XMLGregorianCalendar.class, new XmlGregorianCalendarDeserializer());

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(wrappedCalendarModule);
String json = "{\n"
+ " \"date\":{\n"
+ " \"$numberLong\":\"1551172199214\"\n"
+ " },\n"
+ " \"name\":\"Rick\"\n"
+ "}";
System.out.println(mapper.readValue(json, Wrapper.class));
}
}

class Wrapper {

private XMLGregorianCalendar date;
private String name;

// getters, setters, toString
}

以上代码打印:

Wrapper{date=2019-02-26T09:09:59.214Z, name='Rick'}

关于java - 来自 MongoDB BSON 的 Jackson ObjectMapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54883074/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com