1

使用带有嵌套对象的 Gson 2.2.4 和 JsonReader 进行流式传输。

JSON:

{
"name": "David",
"address": {
    "city": "Bangalore"
},
"role": "Manager"
}

POJO 类:

public class Data {

    private String name;
    private String role;
    private Address address;

    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString(){
        return getName() + "::"+getRole()+"::"+getAddress().getCity();
    }
}


public class Address {

    private String city;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

我的代码:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

public class TestReader {

    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("test.txt");
        InputStreamReader isr = new InputStreamReader(is);

        JsonReader reader = new JsonReader(isr);

        Data data = new Data();
        data.setAddress(new Address());
        String key = null;

        while (reader.hasNext()) {
            JsonToken token = reader.peek();

            switch (token) {
            case BEGIN_OBJECT:
                reader.beginObject();
                break;
            case END_OBJECT:
                reader.endObject();
                break;
            case BEGIN_ARRAY:
                reader.beginArray();
                break;
            case END_ARRAY:
                reader.endArray();
                break;
            case NAME:
                key = reader.nextName();
                break;
            case STRING:
                if ("name".equals(key))
                    data.setName(reader.nextString());
                else if ("role".equals(key))
                    data.setRole(reader.nextString());
                else if ("city".equals(key))
                    data.getAddress().setCity(reader.nextString());
                break;
            case NULL:
                reader.nextNull();
                break;
            case END_DOCUMENT:
                break;
            default:
                break;

            }
        }
        reader.close();

        System.out.println(data);
    }
}

它打印“David::null::Bangalore”,并且在嵌套对象之后无法解析任何内容。如果我将 JSON 更改为

{
"name": "David",
"role": "Manager",
"address": {
    "city": "Bangalore"
}
}

它工作正常并打印“David::Manager::Bangalore”。尝试了很多,但不确定我错过了什么。

4

1 回答 1

3

由于 JSON 本质上是递归的,因此您的方法也应该如此。那就是你需要在地址对象而不是数据上再次调用你的方法。

所以我修复了你的代码(我管理它,以一种天真的方式)在这种特定情况下工作。如果你有一个更复杂的结构,当然方法也会变得更复杂。

package stackoverflow.questions.q19282973;

import java.io.*;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

public class TestReader {

    public static void main(String[] args) throws IOException {
        String json = "{\"name\": \"David\",\"address\": {\"city\": \"Bangalore\"},\"role\": \"Manager\"}";
        String json2 = "{\"name\": \"David\",\"role\": \"Manager\",\"address\": {\"city\": \"Bangalore\"}}";

        InputStream is = new ByteArrayInputStream(json2.getBytes("UTF-8"));
        InputStreamReader isr = new InputStreamReader(is);

        JsonReader reader = new JsonReader(isr);

        Data data = new Data();
        data.setAddress(new Address());
        String key = null;

        key = read(reader, data, key);
        reader.close();

        System.out.println(data);
    }

    private static String read(JsonReader reader, Object obj, String key)
            throws IOException {


        while (reader.hasNext()) {
            JsonToken token = reader.peek();

            switch (token) {
            case BEGIN_OBJECT:
                reader.beginObject();
                if ("address".equals(key)) {

                    while (reader.hasNext()) {
                        read(reader, ((Data) obj).getAddress(), key);
                    }
                    reader.endObject();
                }
                break;
            case END_OBJECT:
                reader.endObject();
                break;
            case BEGIN_ARRAY:
                reader.beginArray();
                break;
            case END_ARRAY:
                reader.endArray();
                break;
            case NAME:
                key = reader.nextName();
                break;
            case STRING:
                if (obj instanceof Data) {
                    Data data = (Data) obj;
                    if ("name".equals(key))
                        data.setName(reader.nextString());
                    else if ("role".equals(key))
                        data.setRole(reader.nextString());
                }
                if (obj instanceof Address) {
                    Address address = (Address) obj;
                    if ("city".equals(key))
                        address.setCity(reader.nextString());
                }
                break;
            case NULL:
                reader.nextNull();
                break;
            case END_DOCUMENT:
                break;
            default:
                break;

            }
        }
        return key;
    }
}

但是为什么要使用 JsonReader呢?它应该仅用于特定情况,并且无论如何它是一个非常低级的 Gson 类。

你只需要这样的东西

Data d = new Gson().fromJson(yourJsonString, Data.class) to parse.

或者,如果您只想解析 JSON 的特定部分,您可以编写自己的反序列化器。

于 2013-10-09T22:33:54.217 回答