1

私は次のjsonを持っています

{
"id":null,
"name":"Myapp",
"description":"application",
"myListA":["java.util.ArrayList",[{
    "id":50,
    "name":"nameA1",
    "myListB":{
        "id":48,
        "name":"nameB1",
        "myListC":["java.util.ArrayList",[{
            "id":1250,
            "name":"nameC1",
            "description":"nameC1_desc",
            "myReferenceObject":{
                "code":"someCodeA"
            }
        },{
            "id":1251,
            "name":"nameC2",
            "description":"nameC1_desc",
            "myReferenceObject":{
                "code":"someCodeB"
            }

等々。

myReferenceObjectを永続層のアイテムに置き換えたいと思います。

JacksonHowToCustomDeserializersをフォローしました

私のデシリアライザーは次のとおりです。

public class MyReferenceObjectCodeDeserializer extends JsonDeserializer<MyReferenceObjectBean> {

    @Override
    public ColumnReferenceBean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {

        while (jp.nextToken() != JsonToken.END_OBJECT) {
            String fieldname = jp.getCurrentName();
            jp.nextToken();
            if ("code".equalsIgnoreCase(fieldname)) {
                MyReferenceObjectBean b = MyReferenceObjectServiceImpl.retrieveByCode(jp.getText());
                logger.info("returning " +b.toString());
                return b;
            }
        }
        logger.info("returning null");
        return null;
    }
}

そして、私はそのようにモジュールを取り付けます:

ObjectMapper mapper = new ObjectMapper();
    mapper.enableDefaultTyping();
    SimpleModule module = new SimpleModule("myModule", new Version(1, 0, 0, null));
    module.addDeserializer(MyReferenceObjectBean.class, new MyReferenceObjectCodeDeserializer());
    
    mapper.registerModule(module);
    try {
        return mapper.readValue(serializedJsonString, MyMainObjectBean.class);
    } catch (IOException e) {
        logger.error("Unable to parse=" + serializedJsonString, e);
    }

すべてが正しくデバッグされますが、結果のmyListCリストには、正しいオブジェクトを保持する偶数のオブジェクトの量が2倍になり、永続性のない正しいmyReferenceObject(モジュールを使用して正しく逆シリアル化されます)と、空のPojoを保持する奇数の要素(nullのオブジェクト)が含まれますすべての変数の値。

デバッグを通じて、実行するたびに正しく機能するため、カスタムデシリアライザーでnullが返されることはありません。この問題は、空白のmyListCオブジェクトを挿入する上流にあるようです。

どんな助けでも喜んでいただければ幸いです。

ありがとう!

4

1 に答える 1

1

コードに論理的な問題があります。オブジェクトの最後に到達するまでループしますが、return b(ブロックの場合)でループを中断します。これは、オブジェクトストリームが最後まで読み取られないことを意味します。

このようなものを試してください(試していないが、動作するはずです)。

public class MyReferenceObjectCodeDeserializer extends JsonDeserializer<MyReferenceObjectBean> {

@Override
public ColumnReferenceBean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    MyReferenceObjectBean b = null;
    while (jp.nextToken() != JsonToken.END_OBJECT) {
        String fieldname = jp.getCurrentName();
        jp.nextToken();
        if ("code".equalsIgnoreCase(fieldname)) {
          b = MyReferenceObjectServiceImpl.retrieveByCode(jp.getText());
          logger.info("returning " +b.toString());
        }
    }
    if (b==null) logger.info("returning null");
    return b;
}
}

ジャクソンから変更できる場合は、Gensonhttp://code.google.com/p/genson/も参照してください。他のいくつかの機能に加えて、それは使いやすいと思われます。gensonの問題を解決する方法は次のとおりです(この例では、jacksonと非常によく似ています)。

public class MyReferenceObjectCodeDeserializer implements Deserializer<MyReferenceObjectBean> {

public MyReferenceObjectBeandeserialize(ObjectReader reader, Context ctx) throws TransformationException, IOException {
        MyReferenceObjectBean b = null;
        reader.beginObject();
        while (reader.hasNext()) {
            reader.next();
            if ("code".equalsIgnoreCase(reader.name()))
                b = MyReferenceObjectServiceImpl.retrieveByCode(reader.valueAsString());
        }
        reader.endObject();
        return b;
    }
}

// register it
Genson genson = new Genson.Builder().withDeserializers(new MyReferenceObjectCodeDeserializer()).create();
MyClass myClass = genson.deserialize(json, MyClass.class);
于 2012-10-29T11:00:33.267 に答える