使用GSON库解析后如何处理json元素?

时间:2019-03-07 12:52:46

标签: java parsing gson

我已将以下有效负载设置到Gson的{​​{1}}中:

JsonObject

测试:

 {
        "backup": {
            "addresses": [
                "127.0.0.1"
            ], 
            "healthcheck_interval": "60", 
            "http": "https", 
            "port": "9001"
        }, 
        "cognito": {
            "addresses": [
                "127.0.0.1"
            ], 
            "http": "https", 
            "port": "9012"
        }, 
        "collector": {
            "addresses": [
                "127.0.0.1"
            ], 
            "healthcheck_interval": "60", 
            "http": "https", 
            "port": "9000"
        }, 
        "ds": {
            "addresses": [
                "127.0.0.1"
            ], 
            "http": "https", 
            "port": "9011"
        }, 
        "insight-analytics": {
            "addresses": [
                "127.0.0.1"
            ], 
            "http": "https", 
            "port": "9013"
        }, 
        "integrations": {
            "addresses": [
                "127.0.0.1"
            ], 
            "http": "https", 
            "port": "9014"
        }, 
        "server": {
            "addresses": [
                "127.0.0.1"
            ], 
            "healthcheck_interval": "60", 
            "http": "https", 
            "port": "9009"
        }, 
        "vigile": {
            "addresses": [
                "127.0.0.1"
            ], 
            "http": "https", 
            "port": "9443"
        }, 
        "walt": {
            "addresses": [
                "127.0.0.1"
            ], 
            "http": "https", 
            "port": "9010"
        }
    }

我希望能够以一种可以将@Test(priority = 10) public void parseServicesFileToGsonObject() { JsonParser jsonParser = new JsonParser(); JsonElement rootNode = jsonParser.parse(response); if (rootNode.isJsonObject()) { JsonObject details = rootNode.getAsJsonObject(); } } 的所有成员存储到字符串数组(JSONbackupcognito等)中的方法使用字符串数组查找对象以获取更多值(例如collectorhealthcheck_intervalhttp等)。我尝试将流用于此原因,但未成功。 我想这样做,因为将来很有可能会更改该字段的名称(而不是port可以更改为另一个名称)。

2 个答案:

答案 0 :(得分:1)

您需要重新考虑您的问题。 GSON的优点在于,它能够从实际的Java对象中反射性地序列化和反序列化JSON。

这意味着您应该首先定义您的对象,然后让GSON进行肮脏的工作,例如:

<ul>
{% for obj in queryset %}
    <li>
    {% for column in obj.column_set.all %}
        [Name of Column]: {{ column }}
    {% endfor %}
    </li>
{% endfor %}
</ul>

这样您就可以拥有

class Server
{
  List<String> addresses;
  int healthcheck_interval;
  String http;
  int port;
}

答案 1 :(得分:1)

最通用的方法是使用Map<String, Object>表示JSON有效负载的动态结构。在那种情况下,我们总是可以使用Map#keySet()方法列出所有属性,而我们不需要任何String[]来保留它们。此外,按键查找对象比使用arrayList更快。如果我们的对象值具有恒定的结构,则可以将其映射到POJO,以便在运行时稳定地访问值。下面的代码显示了两种情况:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        Gson gson = new GsonBuilder().create();

        System.out.println("Use generic Map");
        Type genericMapType = new TypeToken<Map<String, Object>>() {
        }.getType();
        Map<String, Object> map = gson.fromJson(new FileReader(jsonFile), genericMapType);
        map.forEach((k, v) -> System.out.println(k + " => " + v));

        System.out.println();
        System.out.println();

        System.out.println("Use Service Map");
        Type serviceMapType = new TypeToken<Map<String, Service>>() {
        }.getType();
        Map<String, Service> serviceMap = gson.fromJson(new FileReader(jsonFile), serviceMapType);
        serviceMap.forEach((k, v) -> System.out.println(k + " => " + v));
    }
}

class Service {
    private List<String> addresses;

    @SerializedName("healthcheck_interval")
    private int healthCheckInterval;
    private String http;
    private int port;

    public List<String> getAddresses() {
        return addresses;
    }

    public void setAddresses(List<String> addresses) {
        this.addresses = addresses;
    }

    public int getHealthCheckInterval() {
        return healthCheckInterval;
    }

    public void setHealthCheckInterval(int healthCheckInterval) {
        this.healthCheckInterval = healthCheckInterval;
    }

    public String getHttp() {
        return http;
    }

    public void setHttp(String http) {
        this.http = http;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public String toString() {
        return "Service{" +
                "addresses=" + addresses +
                ", healthCheckInterval=" + healthCheckInterval +
                ", http='" + http + '\'' +
                ", port=" + port +
                '}';
    }
}

上面的代码显示:

Use generic Map
backup => {addresses=[127.0.0.1], healthcheck_interval=60, http=https, port=9001}
cognito => {addresses=[127.0.0.1], http=https, port=9012}
collector => {addresses=[127.0.0.1], healthcheck_interval=60, http=https, port=9000}
ds => {addresses=[127.0.0.1], http=https, port=9011}
insight-analytics => {addresses=[127.0.0.1], http=https, port=9013}
integrations => {addresses=[127.0.0.1], http=https, port=9014}
server => {addresses=[127.0.0.1], healthcheck_interval=60, http=https, port=9009}
vigile => {addresses=[127.0.0.1], http=https, port=9443}
walt => {addresses=[127.0.0.1], http=https, port=9010}


Use Service Map
backup => Service{addresses=[127.0.0.1], healthCheckInterval=60, http='https', port=9001}
cognito => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9012}
collector => Service{addresses=[127.0.0.1], healthCheckInterval=60, http='https', port=9000}
ds => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9011}
insight-analytics => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9013}
integrations => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9014}
server => Service{addresses=[127.0.0.1], healthCheckInterval=60, http='https', port=9009}
vigile => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9443}
walt => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9010}