簡體   English   中英

傑克遜定制解串器在閱讀列表時創建空的pojo

[英]Jackson custom deserializers creating empty pojo when reading list

我有以下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列表的對象數量增加了一倍,偶數保持正確的對象以及正確的myReferenceObject而不具有持久性(使用我的模塊正確反序列化),而奇數元素保持空的Pojos,即對象為null所有變量的值。

通過調試,它在我的自定義反序列化器中永遠不會達到return null,因為它每次執行時都能正常工作。 問題似乎更進一步,它會插入空白的myListC對象。

任何幫助將不勝感激。

謝謝!

您的代碼中存在邏輯問題。 您想循環直到到達對象的末尾,但是用返回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;
}
}

如果您可以從傑克遜更改,也可以看看Genson http://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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM