2013-09-27 152 views
2

我有一个非常简单的POJO,我写入MongoDB。然后它返回包含_id属性作为$ oid对象的JSON。我想写入我的POJO,但迄今为止失败了。我看到很多人与它斗争并提出不同的解决方案,但我还没有得到任何解决方案。可能是因为没有人提供确切的细节,他们实际使用的库。有codehaus.jackson。*有com.fastxml.jackson。 ,jongo,org.mongo。,com.mongo *等

我的目标是这样的:

package com.blueplanetsoftware.metrics.rest; 

import javax.persistence.Id; 

import com.fasterxml.jackson.annotation.JsonProperty; 

public class MongoObject 
{ 
    @JsonProperty("_id") 
    private String _id; 

    @JsonProperty("userID") 
    private String userID; 
    @JsonProperty("appID") 
    private String appID; 
    @JsonProperty("message") 
    private String message = ""; 
    @JsonProperty("session") 
    private String session; 

    public MongoObject() {} 

    /** 
    * @return the id 
    */ 
    @Id 
    @JsonProperty("_id") 
    public String getId() 
    { 
     return _id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    @Id 
    @JsonProperty("_id") 
    public void setId(String id) 
    { 
     this._id = id; 
    } 
} 

,我找回了JSON看起来是这样的:

{ 
    "userID" : "aap" , 
    "appID" : "noot" , 
    "message" : "JSON" , 
    "session" : "ea944555b5ea8ea6" , 
    "_id" : { "$oid" : "5245f1063004348555e54815"} 
} 

当我尝试反序列化JSON到我这个代码类:

com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper(); 
MongoObject o = mapper.readValue(response, MongoObject.class); 

它给了我一个例外:

java.lang.AssertionError: Can not deserialize instance of java.lang.String out of START_OBJECT token 
at [Source: [email protected]; line: 1, column: 93] (through reference chain: com.blueplanetsoftware.metrics.rest.MongoObject["_id"]) 

那么如何让_id/$ oid字符串进入我的_id属性?我很惊讶,这不是一个简单的方法来做到这一点。至少我至今还没有找到任何东西。

回答

4

你试过了吗?

@ObjectId @Id 
private String id; 

我写了一个测试,看看这方面的工作:

@Test 
public void shouldConvertJSONStringIntoPojo() throws IOException { 
    ObjectMapper mapper = new ObjectMapper(); 
    MongoObject actual = mapper.readValue("{\n" + 
            "  \"userID\" : \"aap\" ,\n" + 
            "  \"appID\" : \"noot\" ,\n" + 
            "  \"message\" : \"JSON\" ,\n" + 
            "  \"session\" : \"ea944555b5ea8ea6\" ,\n" + 
            "  \"_id\" : { \"$oid\" : \"5245f1063004348555e54815\"}\n" + 
            "}", MongoObject.class); 

    assertThat(actual, equalTo(new MongoObject("5245f1063004348555e54815", "aap", "noot", "JSON", "ea944555b5ea8ea6"))); 
} 

我使用这个文库:

import com.fasterxml.jackson.databind.ObjectMapper; (jackson-databind-2.1.4,jar) 
import org.junit.Test;        (junit-4.11.jar) 
import static org.hamcrest.CoreMatchers.equalTo; (hamcrest-core-1.3.jar) 
import static org.junit.Assert.assertThat;   (junit-4.11.jar) 

唯一的变化,我给你做在问题中发布的MongoObject添加了一个构造函数,该构造函数将所有字段和hashCode等于& toString(这样我就可以测试它)。如果我运行与MongoObject该测试,然后我得到了同样的错误,你:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token 
at [Source: [email protected]; line: 5, column: 40] (through reference chain: MongoObject["_id"]) 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) 
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599) 

但是,如果我做一个小的变化,以您的MongoObject:

public class MongoObject 
{ 
    @JsonProperty("_id") 
    @org.jongo.marshall.jackson.oid.ObjectId 
    private String _id; 

    @JsonProperty("userID") 
    private String userID; 
    @JsonProperty("appID") 
    private String appID; 
    @JsonProperty("message") 
    private String message; 
    @JsonProperty("session") 
    private String session; 

    public MongoObject() {} 

//... insert constructors, hashCode, equals and toString just for testing... 
} 

,则测试通过。

+0

我想我试过了。但是,@ObjectId来自MongoJack库。尽管MongoJack似乎可以直接将MongoDB查询转换为POJO,但我无法找到如何使用MongoJack将JSON字符串转换为POJO,反之亦然。由于我正在创建一个平台和语言不可知的REST服务,因此我的REST代码需要返回JSON字符串。在客户端,使用Java时,我想将这些字符串转换为POJO。这就是_id:{$ 0id:“abc”}结构给出的麻烦。我在这里错过了一些微不足道的东西吗? –

+0

我认为我使用的是Jongo,它非常适合查询。 MongoJack和Jongo不一样。在MongoJack中,你可以给JacksonDBCollection POJO来保存,但我想这仍然不能回答你的问题,因为你仍然需要获得POJO。在我的项目中,杰克逊数据绑定似乎正在关注事物的这一方面。如果有帮助,我会用我写的junit测试更新我的答案。 – Trisha

+0

谢谢Trisha,确实有效。我觉得非常好奇,因为它没有@ org.jongo.marshall.jackson.oid.ObjectId注解不起作用。尽管这是对Jongo的唯一参考。这是否意味着com.fasterxml.jackson.databind.ObjectMapper知道Jongo注释?这个解决方案有一些神奇的东西,没有任何意义。但至少它解决了我的问题,我会看看我以后能否理解它。 –