Java 是否可以使用Gson将JSON层次结构扁平化?

Java 是否可以使用Gson将JSON层次结构扁平化?,java,json,gson,Java,Json,Gson,我使用Gson将JSON数据转换为Java对象。但是,JSON结构有一个可以展平的额外字段。这可能与Gson有关吗 为了详细说明(因为这很难解释),JSON看起来如下所示: { "foo": "bar", "data": { "first": 0, "second": 1, "third": 2 } } public class Entry { private String foo; private Dat

我使用Gson将JSON数据转换为Java对象。但是,JSON结构有一个可以展平的额外字段。这可能与Gson有关吗

为了详细说明(因为这很难解释),JSON看起来如下所示:

{
    "foo": "bar",
    "data": {
        "first": 0,
        "second": 1,
        "third": 2
    }
}
public class Entry {
    private String foo;
    private Data data;
}

public class Data {
    private int first;
    private int second;
    private int third;
}
public class Entry {
    private String foo; 
    private int first;
    private int second;
    private int third;
}
// even more complicated version without inner Gson help
public Entry readOption2(JsonReader in) throws IOException {
    Entry entry = new Entry();
    in.beginObject();
    while (in.hasNext()) {
        String name = in.nextName();
        if (name.equals("foo")) {
            entry.foo = in.nextString();
        } else if (name.equals("data")) {
            in.beginObject();
            while (in.hasNext()) {
                name = in.nextName();
                if (name.equals("first")) {
                    entry.first = in.nextInt();
                } else if (name.equals("second")) {
                    entry.second = in.nextInt();
                } else if (name.equals("third")) {
                    entry.third = in.nextInt();
                }else{
                    in.skipValue();
                }
            }
            in.endObject();
        } else {
            in.skipValue();
        }
    }
    in.endObject();
    return entry;
}
这将生成两个类,一个用于父类,另一个用于
数据
,如下所示:

{
    "foo": "bar",
    "data": {
        "first": 0,
        "second": 1,
        "third": 2
    }
}
public class Entry {
    private String foo;
    private Data data;
}

public class Data {
    private int first;
    private int second;
    private int third;
}
public class Entry {
    private String foo; 
    private int first;
    private int second;
    private int third;
}
// even more complicated version without inner Gson help
public Entry readOption2(JsonReader in) throws IOException {
    Entry entry = new Entry();
    in.beginObject();
    while (in.hasNext()) {
        String name = in.nextName();
        if (name.equals("foo")) {
            entry.foo = in.nextString();
        } else if (name.equals("data")) {
            in.beginObject();
            while (in.hasNext()) {
                name = in.nextName();
                if (name.equals("first")) {
                    entry.first = in.nextInt();
                } else if (name.equals("second")) {
                    entry.second = in.nextInt();
                } else if (name.equals("third")) {
                    entry.third = in.nextInt();
                }else{
                    in.skipValue();
                }
            }
            in.endObject();
        } else {
            in.skipValue();
        }
    }
    in.endObject();
    return entry;
}
我想将
数据
字段“展平”到父对象中,以便Java类看起来像这样:

{
    "foo": "bar",
    "data": {
        "first": 0,
        "second": 1,
        "third": 2
    }
}
public class Entry {
    private String foo;
    private Data data;
}

public class Data {
    private int first;
    private int second;
    private int third;
}
public class Entry {
    private String foo; 
    private int first;
    private int second;
    private int third;
}
// even more complicated version without inner Gson help
public Entry readOption2(JsonReader in) throws IOException {
    Entry entry = new Entry();
    in.beginObject();
    while (in.hasNext()) {
        String name = in.nextName();
        if (name.equals("foo")) {
            entry.foo = in.nextString();
        } else if (name.equals("data")) {
            in.beginObject();
            while (in.hasNext()) {
                name = in.nextName();
                if (name.equals("first")) {
                    entry.first = in.nextInt();
                } else if (name.equals("second")) {
                    entry.second = in.nextInt();
                } else if (name.equals("third")) {
                    entry.third = in.nextInt();
                }else{
                    in.skipValue();
                }
            }
            in.endObject();
        } else {
            in.skipValue();
        }
    }
    in.endObject();
    return entry;
}

使用Gson,例如使用TypeAdapters,这是否可行?

我将向您展示演示,您自己决定是否真的需要这个。。。因为它使
TypeAdapter
代码难以阅读

private static class EntryTypeAdapter extends TypeAdapter<Entry> {
    // without registerTypeAdapter(Entry.class, new EntryTypeAdapter())
    private Gson gson = new GsonBuilder()
            // ignore "foo" from deserialization and serialization
            .setExclusionStrategies(new TestExclStrat()).create();

    @Override
    public void write(JsonWriter out, Entry value) throws IOException {
        out.beginObject();
        out.name("foo");
        out.value(value.foo);
        out.name("data");
        out.value(gson.toJson(value));
        out.endObject();
    }

    @Override
    public Entry read(JsonReader in) throws IOException {
        Entry entry = null;
        String foo = null;
        in.beginObject();
        while (in.hasNext()) {
            String name = in.nextName();
            if (name.equals("foo")) {
                foo = in.nextString();
            } else if (name.equals("data")) {
                entry = gson.fromJson(in, Entry.class);
            } else {
                in.skipValue();
            }
        }
        in.endObject();
        if(entry!= null) entry.foo = foo;
        return entry;
    }

    public class TestExclStrat implements ExclusionStrategy {
        public boolean shouldSkipClass(Class<?> arg0) {
            return false;
        }
        public boolean shouldSkipField(FieldAttributes f) {
            return f.getName().equals("foo");
        }
    }
}
你也可以这样做:

{
    "foo": "bar",
    "data": {
        "first": 0,
        "second": 1,
        "third": 2
    }
}
public class Entry {
    private String foo;
    private Data data;
}

public class Data {
    private int first;
    private int second;
    private int third;
}
public class Entry {
    private String foo; 
    private int first;
    private int second;
    private int third;
}
// even more complicated version without inner Gson help
public Entry readOption2(JsonReader in) throws IOException {
    Entry entry = new Entry();
    in.beginObject();
    while (in.hasNext()) {
        String name = in.nextName();
        if (name.equals("foo")) {
            entry.foo = in.nextString();
        } else if (name.equals("data")) {
            in.beginObject();
            while (in.hasNext()) {
                name = in.nextName();
                if (name.equals("first")) {
                    entry.first = in.nextInt();
                } else if (name.equals("second")) {
                    entry.second = in.nextInt();
                } else if (name.equals("third")) {
                    entry.third = in.nextInt();
                }else{
                    in.skipValue();
                }
            }
            in.endObject();
        } else {
            in.skipValue();
        }
    }
    in.endObject();
    return entry;
}

编写一个实现JsonDeserializer@EduardoYáñezParareda想以答案的形式给出一个例子吗?下面是一个关于JsonDeserializer的答案