如何创建JSON数据结构时,元素可以是不同类型的供(How do I create JSON dat

2019-09-28 04:33发布

在这个问题 ,我们看到孩子们元素可以是额外的数据项或一个布尔值数组

我使用Java在数据类来创建数据存储,然后使用谷歌GSON转换成JSON。 但是因为孩子可以有两种不同的事情,我已经通过在我的数据变量的孩子 ,当我需要存储为布尔值,我用这个来表示。 然后做一个字符串替换生成的JSON把它变成一个儿童元素。

但这种黑客也不是很理想和有问题(即,如果他们有内容的“孩子”真实数据),那么什么是代表具有不同的数据类型的数据的正确方法。

public class Data
{
    private String id;
    private String text;
    private String icon;
    private State  state;
    private boolean kids;

    private List<Data> children = null;

    public String getId()
    {
        return id;
    }

    public void setId(String id)
    {
        this.id = id;
    }

    public String getText()
    {
        return text;
    }

    public void setText(String text)
    {
        this.text = text;
    }

    public String getIcon()
    {
        return icon;
    }

    public void setIcon(String icon)
    {
        this.icon = icon;
    }

    public List<Data> getChildren()
    {
        return children;
    }

    public void setChildren(List<Data> children)
    {
        this.children = children;
    }

    public State getState()
    {
        return state;
    }

    public void setState(State state)
    {
        this.state = state;
    }

    public boolean getKids()
    {
        return kids;
    }

    public void setKids(boolean kids)
    {
        this.kids = kids;
    }
}

public static String createFolderJsonData()
{
  CreateFolderTree cft = new CreateFolderTree(null);
  String treeData = cft.start(1).replace("kids", "children");
  return treeData;
}

Answer 1:

假设你知道孩子是什么类型的,你可以解决它像这样

public class Data<T>{

    private T children = null;

    public T getChildren(){
        return children;
    }

    public void setChildren(T children){
        this.children = children;
    }
}

public class DataRunner {
    public static void main(String[] args){
        Data<List<Data>> data = new Data<>();

        Data<List<Data>> subDataOne = new Data<>();
        subDataOne.setChildren(new ArrayList<>());

        Data<Boolean> subDataTwo = new Data<>();
        subDataTwo.setChildren(true);

        List<Data> listData = new ArrayList<>();

        listData.add(subDataOne);
        listData.add(subDataTwo);

        data.setChildren(listData);

        // {"children":[{"children":[]},{"children":true}]}
        System.out.println(new Gson().toJson(data));
    }
}

现在,它打印正确的事情,注意ArrayList不关心泛型类型Data



Answer 2:

对于反序列化:

你得把两个班,一个是Boolean类型(我把它命名为BoolData ),一个用于List<Data>键入( ListData )。 然后,你可以写一个自定义JsonDeserializer谁将会反序列化对象BoolDataListData ,使用JSON值来决定使用哪种类型。

型号:

public abstract class Data<T> {

    private String id;

    private T children;

    // ...
    public Data() {
    }

    public String getId() {
        return id;
    }

    public T getChildren() {
        return children;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setChildren(T children) {
        this.children = children;
    }

    @Override
    public String toString() {
        return "Data{" + "id=" + id + ", children=" + children + '}';
    }
}

public class ListData extends Data<List<Data<?>>> {
}

public class BoolData extends Data<Boolean> {
}

解串器:

String json = ""
        + "["
        + "  {"
        + "    \"id\": \"1\""
        + "  },"
        + "  {"
        + "    \"id\": \"2\","
        + "    \"children\": ["
        + "       {"
        + "         \"id\": \"2.1\","
        + "         \"children\": true"
        + "       },"
        + "       {"
        + "         \"id\": \"2.2\","
        + "         \"children\": []"
        + "       }"
        + "    ]"
        + "  }"
        + "]";
    List<Data<?>> data = new GsonBuilder()
        .registerTypeAdapter(Data.class, (JsonDeserializer<Data<?>>) (elem, type, ctx) -> {
            JsonObject obj = elem.getAsJsonObject();
            JsonElement children = obj.get("children");

            // If "children" is a boolean, deserialize it as BoolData
            return children != null && children.isJsonPrimitive() && children.getAsJsonPrimitive().isBoolean()
                ? ctx.deserialize(elem, BoolData.class)
                : ctx.deserialize(elem, ListData.class);
        })
        .create()
        .fromJson(json, new TypeToken<List<Data<?>>>() {
        }.getType());
    System.out.println(data);

输出:

[Data{id=1, children=null}, Data{id=2, children=[Data{id=2.1, children=true}, Data{id=2.2, children=[]}]}]

JSON使用:

[
    {
        "id": "1"
    },
    {
        "id": "2",
        "children": [
            {
                "id": "2.1",
                "children": true
            }, {
                "id": "2.2",
                "children": []
            }
        ]
    }
]


文章来源: How do I create JSON data structure when element can be different types in for use by
标签: java gson