笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述来自MongoDB BSON的Jackson ObjectMapper相关的知识,希望能为你提供帮助。
【来自MongoDB BSON的Jackson ObjectMapper】我得到了一个JSON,我将其序列化为MongoDB BasicDBObject并将其插入到DB中:
String serialized = "";
try {
serialized = OBJECT_MAPPER.writeValueAsString(customEx.getOut().getBody());
} catch (JsonProcessingException e) {
e.printStackTrace();
}collection.update(upsertQuery, BasicDBObject.parse(serialized), true, false);
在从DB读取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生成的,还包含时间戳/长值,如下所示:
@XmlRootElement(name = "ItemType")
public class ItemType {@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar date;
[...]
但是,这适用于较旧的java MongoDB版本。现在长值被序列化为BSON,如下所示:
"date": {
"$numberLong": "1551172199214"
}
当我尝试使用Jacksons ObjectMapper反序列化时,我得到了
无法从START_OBJECT标记中反序列化这个的原因很清楚,因为long值在一个自己的BSON-Style对象中。javax.xml.datatype.XMLGregorianCalendar
的实例
到目前为止,我已经尝试过像这样使用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部件?
答案看起来您需要配置ObjectMapper以不同方式反序列化XMLGregorianCalendar。
public class XMLGregorianCalendarDeserializer extends JsonDeserializer<
XMLGregorianCalendar>
{
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public XMLGregorianCalendar deserialize(
JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
Map<
String, String>
bsonStringAsMap =
objectMapper.readValue(
jsonParser.readValueAsTree().toString(), new TypeReference<
Map<
String, String>
>
() {});
String timestampString = bsonStringAsMap.get("$numberLong");
if (timestampString != null &
&
!timestampString.isEmpty()) {
long timestamp = Long.parseLong(timestampString);
Date date = new Date(timestamp);
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTime(date);
return DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar);
}
return null;
}
}
然后你可以用这个注释字段并反序列化:
@JsonDeserialize(using=XMLGregorianCalendarDeserializer.class)
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar date;
另一答案如果日历字段被包装,我们需要打开它。我们可以扩展已经实现的
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_STRINGXMLGregorianCalendar calendar = super.deserialize(jp, ctxt);
jp.nextToken();
// Skip END_OBJECTreturn calendar;
}
}
如果总是包裹
XMLGregorianCalendar
,我们可以使用SimpleModule
注册这个deserialiser。见下面的例子: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 = "{
"
+ ""date":{
"
+ ""$numberLong":"1551172199214"
"
+ "},
"
+ ""name":"Rick"
"
+ "}";
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'}
推荐阅读
- 引用oracle apex APP_USER
- Flask,Pymongo和Mongoengine - ImportError(无法导入名称'app')
- 使用Hibernate App在Java中更改PostgreSQL的MySql时出错
- 错误(TypeError('app.use()需要中间件函数)
- 为你的企业雇用WordPress开发人员的建议
- Genesis智能标题–在滚动条上隐藏但在滚动条上显示
- 11个创建独特WordPress网站的最佳多用途主题
- 如何在Genesis Authority Pro标头中添加搜索图标()
- 如何允许贡献者在WordPress中上传图片()