7

わかりました。最初に、Web サービスから返される JSON を示します。Android ContentProvider の ResponseHandler で非同期クエリを実行した後、それを pojos に逆シリアル化しようとしています。

{"exampleList" : [{
"locationId" : "00001" , 
"owners" : [ 
  { 
    "paidID" : { "$oid" : "50a9c951300493f64fbffdb6"} , 
    "userID" : { "$oid" : "50a9c951300493f64fbffdb6"}
  } , 
  { 
    "paidID" : { "$oid" : "50a9c951300493f64fbffdb7"} , 
    "userID" : { "$oid" : "50a9c951300493f64fbffdb7"}
  } 
]
}]}

最初は、Android アプリと同じように Web サービスに Jackson アノテーション付きの Bean を使用しているため、この問題に戸惑いましたがowners、サンプルの JSON でオブジェクトが送信されていないことに気付きました。 Web サービスに追加します (Web サービスの POJO をスキップし、DAO からのアトミック更新によって mongoDB のドキュメントに追加されます)。

じゃあ良いよ。これまで、Jackson はownersオブジェクトを処理する必要がありませんでした。

JsonMappingException:参照チェーン [所有者クラスを含むジャクソン Bean へのパス] を介して [見つけられる文字位置] で、トークンjava.lang.String外の インスタンスをデシリアライズできませんSTART_OBJECT"userID""paidID"

私のJackson Beanにはラッパーがあり、これが「exampleList」のすべてです。

public class Examples extends HashMap<String, ArrayList<Example>> {

}

そして、実際の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;
    }

}

}

そして最後に、これがすべて失敗している ResponseHandler のコード (2 行目で JsonMappingException が生成されます):

objectMapper = MongoJacksonMapperModule.configure(objectMapper);    
mExamples = objectMapper.readValue(jsonParser, Examples.class);

$oid問題は、JacksonがまだmongoDB ObjectIdsであるそれらをマップする方法を知らないということだと感じています。MongoJacksonMapper ライブラリは、@ObjectIdアノテーションと、そのライブラリを使用するように ObjectMapper を構成する方法を提供することで、これを支援するはずですが、まだ機能していません。何らかの理由で、ObjectId ではなく文字列として userID または payedID を検索しています。何か案は?

4

6 に答える 6

20

別の選択肢は com.fasterxml.jackson.databind.ser.std.ToStringSerializerです。

@Id
@JsonSerialize(using = ToStringSerializer.class)
private final ObjectId id;

これにより、次のようになります。

{
  "id": "5489f420c8306b6ac8d33897"
}
于 2014-12-11T19:59:49.600 に答える
2

私のコードには少なくとも2つの問題があり、オンラインでの回答を追跡するのはかなり困難だったので、ここにリンクするようにします。基本的に、子クラスには、子をマップするためにJacksonのreadValue()を呼び出す親クラスのコンストラクターが必要です。mongoDB $ oidに関しては、これらのmongoオブジェクトを表す別のMongoIdクラスを作成し、子クラスと同様のパターンに従って、データが逆シリアル化されるときにデータをマップする必要があります。これは私が見つけたブログ投稿で、これをうまく説明し、いくつかの例を提供しています。

于 2012-12-30T21:47:21.060 に答える
2

Jackson は、ObjectId をシリアル化する方法を知りません。Arny のコードを微調整して ObjectId をシリアル化し、次の作業例を提供します。

public class SerialiserTest {

 private ObjectMapper mapper = new ObjectMapper();

 public static class T {
    private ObjectId objectId;

    public ObjectId getObjectId() {
        return objectId;
    }

    public void setObjectId(ObjectId objectId) {
        this.objectId = objectId;
    }
 }

 @Test
 public final void serDeser() throws IOException {
    T t = new T();
    t.setObjectId(new ObjectId());
    List<T> ls = Collections.singletonList(t);
    String json = mapper.writeValueAsString(ls);
    System.out.println(json);
    SimpleModule mod = new SimpleModule("ObjectId", new Version(1, 0, 0, null, null, null));
    mod.addDeserializer(ObjectId.class, new ObjectIdDeserializer());
    mapper.registerModule(mod);
    JavaType type = mapper.getTypeFactory().
            constructCollectionType(List.class, T.class);
    List<?> l  = mapper.readValue(json, type);
    System.out.println(l);
 }
}

public class ObjectIdDeserializer extends JsonDeserializer<ObjectId> {

 @Override
 public ObjectId deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    JsonNode n = (JsonNode)p.readValueAsTree();
    return new ObjectId(n.get("timestamp").asInt(), n.get("machineIdentifier").asInt(), (short) n.get("processIdentifier").asInt(), n.get("counter").asInt());
 }

}
于 2017-07-07T16:06:10.877 に答える