Mat*_*t M 4 json jackson mongo-jackson-mapper
好的,首先,这是从我的Web服务返回的JSON.我试图在Android ContentProvider中的ResponseHandler中进行异步查询后将其反序列化为pojos.
{"exampleList" : [{
"locationId" : "00001" ,
"owners" : [
{
"paidID" : { "$oid" : "50a9c951300493f64fbffdb6"} ,
"userID" : { "$oid" : "50a9c951300493f64fbffdb6"}
} ,
{
"paidID" : { "$oid" : "50a9c951300493f64fbffdb7"} ,
"userID" : { "$oid" : "50a9c951300493f64fbffdb7"}
}
]
}]}
Run Code Online (Sandbox Code Playgroud)
起初,我对我看到的问题感到困惑,因为我在我的Android应用程序中使用与我的Web服务相同的Jackson注释bean - 但后来我意识到该owners对象永远不会在示例JSON中发送到我的Web服务(它跳过我的Web服务上的POJO并通过DAO的原子更新添加到mongoDB中的文档中).
那么好吧.到目前为止,杰克逊不必处理这个owners对象,现在它正在窒息,即:
JsonMappingException:无法反序列化的情况下java.lang.String进行的START_OBJECT,在[字符位置,你可以找到令牌"userID",并"paidID"通过参考链] [路径到我的杰克逊豆含有车主类]
我的Jackson bean有一个包装器,这就是"exampleList"的全部内容:
public class Examples extends HashMap<String, ArrayList<Example>> {
}
Run Code Online (Sandbox Code Playgroud)
然后是实际的Example课程:
@JsonIgnoreProperties(ignoreUnknown = true)
public class Example implements Comparable<Example> {
@ObjectId @Id
private String id;
@JsonProperty(Constants.Example.location)
private String location;
@JsonProperty(Constants.Example.OWNERS)
private List<Owners> owners;
public int compareTo(Example _o) {
return getId().compareTo(_o.getId());
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public List<Example.Owners> getOwners() {
return owners;
}
public void setOwners(List<Example.Owners> owners) {
this.owners = owners;
}
public Example() {
}
@JsonCreator
public Example(@Id @ObjectId String id) {
this.id = id;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Owners implements Comparable<Owners> {
@JsonProperty(Constants.Example.USERID)
private String userID;
@JsonProperty(Constants.Example.PAIDID)
private String paidID;
public Owners() {
}
public int compareTo(Owners _o) {
return getUserID().compareTo(_o.getUserID());
}
@ObjectId
public String getUserID() {
return userID;
}
@ObjectId
public void setUserID(String userID) {
this.userID = userID;
}
@ObjectId
public String getPaidID() {
return paidID;
}
@ObjectId
public void setPaidID(String paidID) {
this.paidID = paidID;
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,ResponseHandler中的代码全部失败(第二行产生JsonMappingException):
objectMapper = MongoJacksonMapperModule.configure(objectMapper);
mExamples = objectMapper.readValue(jsonParser, Examples.class);
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,问题是杰克逊仍然不知道如何映射那些$oid,即mongoDB ObjectIds.MongoJacksonMapper库应该通过提供@ObjectId注释和配置ObjectMapper以使用该库的方式来帮助它,但它仍然无法正常工作.出于某种原因,它仍然在寻找userID或paidID作为String,而不是ObjectId.有任何想法吗?
wbi*_*ler 15
另一种选择是
com.fasterxml.jackson.databind.ser.std.ToStringSerializer.
@Id
@JsonSerialize(using = ToStringSerializer.class)
private final ObjectId id;
Run Code Online (Sandbox Code Playgroud)
这将导致:
{
"id": "5489f420c8306b6ac8d33897"
}
Run Code Online (Sandbox Code Playgroud)
对于未来的用户:使用自定义的 jackson 反序列化器将 $oid 转换回 ObjectId。
public class ObjectIdDeserializer extends JsonDeserializer<ObjectId> {
@Override
public ObjectId deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode oid = ((JsonNode)p.readValueAsTree()).get("$oid");
return new ObjectId(oid.asText());
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用:
ObjectMapper mapper = new ObjectMapper();
SimpleModule mod = new SimpleModule("ObjectId", new Version(1, 0, 0, null, null, null));
mod.addDeserializer(ObjectId.class, new ObjectIdDeserializer());
mapper.registerModule(mod);
YourClass obj = mapper.readValue("{your json with $oid}", YourClass.class);
Run Code Online (Sandbox Code Playgroud)
我的代码至少有两个问题很难在网上找到答案,所以我会确保链接到这里。基本上,子类需要父类中的构造函数来调用 Jackson 的 readValue() 来映射子类。就 mongoDB $oid 而言,您应该创建一个单独的 MongoId 类来表示这些 mongo 对象,并遵循与子类类似的模式来在数据进行反序列化时映射数据。这是我发现的一篇博客文章,很好地描述了这一点并提供了一些示例。
| 归档时间: |
|
| 查看次数: |
15693 次 |
| 最近记录: |