我可以将自定义解串器应用于GSON的另一个自定义解串器吗? [英] Can I apply a custom deserializer to within another custom deserializer for GSON

查看:101
本文介绍了我可以将自定义解串器应用于GSON的另一个自定义解串器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个工作代码,它有助于在Object中相应地转换JSON。如果字符串是 nil ,它将被视为空。

The below is a working code that helps to convert JSON in Object accordingly. If the String is nil, it will be treated as null.

有2个自定义反序列化器,即 MyOwnStringDeserializer MyOwnListDeserializer 。我对 MyOwnListDeserializer 反序列化器不满意,因为它所做的实际上是根据字符串与 MyOwnStringDeserializer 。但我不能也不知道如何将 MyOwnStringDeserializer 应用到 MyOwnListDeserializer 中。

There's 2 custom deserializer i.e. MyOwnStringDeserializer and MyOwnListDeserializer. I am not happy with MyOwnListDeserializer deserializer, as essentially what it is doing is in term of the String comparison to the rule defined in MyOwnStringDeserializer. But I just can't and don't know how to apply the MyOwnStringDeserializer into MyOwnListDeserializer.

有没有办法让我这么做,简化 MyOwnListDeserializer ?或甚至更好,如果有一种方法只使用一个自定义反序列化器,并仍然可以达到相同的结果?

Is there a way for me to do so, that simplify the MyOwnListDeserializer? Or even better if there's a way to use just a single custom deserializer and could still achieve the same result?

@Test
public void myTestFunction() {
    String myJson1 = "{\"item1\":\"nil\",\"item2\":\"nil\",\"subItemList\":[{\"subItem1\":\"nil\",\"subItem2\":\"nil\"}]}";
    String myJson2 = "{\"subItemList\":[]}";

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(new TypeToken<List<MySubItems>>(){ }.getType(), new MyOwnListDeserializer());
    gsonBuilder.registerTypeAdapter(String.class, new MyOwnStringDeserializer());
    Gson gson = gsonBuilder.create();

    MySimpleObject myObj1 = gson.fromJson(myJson1, MySimpleObject.class);
    MySimpleObject myObj2 = gson.fromJson(myJson2, MySimpleObject.class);

    assertThat(myObj1.equals((myObj2))).isTrue();
}

class MySimpleObject implements Serializable {
    String item1 = null;
    String item2 = null;
    List<MySubItems> subItemList;

    @Override
    public int hashCode() {
        int hash = 17;
        hash = 31*hash + ((item1 == null)? 0 :item1.hashCode());
        hash = 31*hash + ((item2 == null)? 0 :item2.hashCode());
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MySimpleObject) {
            return this.hashCode() == obj.hashCode();
        }
        return super.equals(obj);
    }
}

class MySubItems implements Serializable {
    String subItem1 = null;
    String subItem2 = null;

    @Override
    public int hashCode() {
        int hash = 17;
        hash = 31*hash + ((subItem1 == null)? 0 :subItem1.hashCode());
        hash = 31*hash + ((subItem2 == null)? 0 :subItem2.hashCode());
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MySubItems) {
            return this.hashCode() == obj.hashCode();
        }
        return super.equals(obj);
    }
}

class MyOwnStringDeserializer implements JsonDeserializer<String> {
    @Override
    public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return (json.getAsString().equals("nil"))? null : json.getAsString();
    }
}

class MyOwnListDeserializer implements JsonDeserializer<List<MySubItems>> {
    @Override
    public List<MySubItems> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        List<MySubItems> list = new ArrayList<>();

        for (JsonElement element : json.getAsJsonArray()) {
            JsonObject subObj = element.getAsJsonObject();
            MySubItems subItems = new MySubItems();

            if (!subObj.get("subItem1").getAsString().equals("nil")) {
                subItems.subItem1 = subObj.get("subItem1").getAsString();
            }
            if (!subObj.get("subItem2").getAsString().equals("nil")) {
                subItems.subItem2 = subObj.get("subItem1").getAsString();
            }

            if (subItems.subItem1 != null || subItems.subItem2 != null) {
                list.add(subItems);
            }
        }

        return (list.size() == 0)? null : list;
    }
}


推荐答案

您正在寻找的方法是 JsonDeserializationContext.deserialize() 。根据关于如何导致无限循环的警告,这会调用您设置的任何相关的自定义反序列化器。

The method you're looking for is JsonDeserializationContext.deserialize(). Per the warning about how to cause an infinite loop, this invokes any relevant custom deserializers you've set up.

我相信替换子元素循环内部带有一行 MySubItems subItems = context.deserialize(element,MySubItems.class); 会执行这个技巧,只留下并在循环体中检查 list.add(subItems)

I believe replacing the initialization of subItems inside the loop with a one-liner MySubItems subItems = context.deserialize(element, MySubItems.class); will do the trick, leaving only that and the check around list.add(subItems) in the loop body.

这篇关于我可以将自定义解串器应用于GSON的另一个自定义解串器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆