繁体   English   中英

使用GSON解析JSON文件

[英]Parsing a JSON file with GSON

我在将JSON文件读入POJO时遇到问题。 让我给你一个我的JSON文件包含的片段:

 {
    "Speidy": {
        "factionId": "2",
        "role": "ADMIN",
        "title": "",
        "power": 9.692296666666667,
        "powerBoost": 0.0,
        "lastPowerUpdateTime": 1337023306922,
        "lastLoginTime": 1337023306922,
        "chatMode": "PUBLIC"
    },
    "ShadowSlayer272": {
        "factionId": "2",
        "role": "NORMAL",
        "title": "",
        "power": 0.8673466666666667,
        "powerBoost": 0.0,
        "lastPowerUpdateTime": 1336945426926,
        "lastLoginTime": 1336945426926,
        "chatMode": "PUBLIC"
    },

我的问题是第一个“节点”是完全随机的,即如果它每次都不同,我怎么能为它制作一个POJO文件呢?

我的子数据的POJO文件是这样的:

public class Node {
    private int factionId = 0;
    private String role = "";
    private String title = "";
    private double power = 0.0;
    private double powerBoost = 0.0;
    private int lastPowerUpdateTime = 0;
    private int lastLoginTime = 0;
    private String chatMode = "";
}

然后我的其他POJO文件是这样的:

public class Container {
    private List<Node> nodes; //What should nodes be for GSON to get each random one?

    public List<Node> getNodes() {
        return nodes;
    }
}

感谢所有的帮助,谢谢。

UPDATE

我尝试将List更改为Map

public class Container {
    private Map<String,Node> nodes;

    public Map<String,Node> getNodes() {
        return nodes;
    }

同时保持节点文件相同。 然后该字符串将是属性名称,即SpeidyShadowSlayer272 但是,gson从不对节点做任何事情,当我尝试getNodes getNodes() ,它返回一个null对象。

谢谢您的帮助。

您列出了一个名称,您可能想要表示一个值,作为对象的属性名称。 相反,在JSON字符串中包含该名称,并为其分配一个属性名称,该名称实际上将在Java Node类中显示为私有变量(带有getter和setter)。

有了这个,您应该能够将JSON反序列化为对象。 此外,因为在服务器端,您将Node集合表示为List,所以我将JSON转换为包含两个对象的数组。 在JavaScript中,您可以将它们作为node[0].namenode[1].name ,它们等同于服务器端的nodes.get(0).getName()

[
    {
        "name" : "Speidy",
        "factionId": "2",
        "role": "ADMIN",
        "title": "",
        "power": 9.692296666666667,
        "powerBoost": 0.0,
        "lastPowerUpdateTime": 1337023306922,
        "lastLoginTime": 1337023306922,
        "chatMode": "PUBLIC"
    },
    {
        "name" : "ShadowSlayer272",
        "factionId": "2",
        "role": "NORMAL",
        "title": "",
        "power": 0.8673466666666667,
        "powerBoost": 0.0,
        "lastPowerUpdateTime": 1336945426926,
        "lastLoginTime": 1336945426926,
        "chatMode": "PUBLIC"
    }
]

public class Node {
    private String name = "";

    private int factionId = 0;
    private String role = "";
    private String title = "";
    private double power = 0.0;
    private double powerBoost = 0.0;
    private int lastPowerUpdateTime = 0;
    private int lastLoginTime = 0;
    private String chatMode = "";
}

话虽如此,如果您确实需要使用该名称作为属性名称,那么请考虑将JSON反序列化为HashMap而不是List。 列表通常映射到JSON数组,而Maps通常更适合表示父对象内的多个JSON对象。

如果你确实控制了JSON的格式,我建议jmort253在他的答案中建议的整体列表结构 ,即[{"name":"Speidy", ... },{"name":"ShadowSlayer272", ... }]

如果您无法控制生成的JSON,可以通过以下两种方式映射JSON代码段,例如您的问题{"Speidy":{ ... },"ShadowSlayer272":{ ... }}与Gson:

  • 没有您的Container类和一点TypeToken伏都TypeToken

     // Ask Gson to deserialize the JSON snippet into a Map<String, Node>. Type type = new TypeToken<Map<String, Node>>() {}.getType(); Map<String, Node> nodes = gson.fromJson(json, type); 
  • 使用您的Container类和自定义JsonDeserializer

     class ContainerDeserializer implements JsonDeserializer<Container> { public Container deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { List<Node> nodes = new ArrayList<Node>(); JsonObject players = json.getAsJsonObject(); for (Entry<String, JsonElement> player : players.entrySet()) { String playerName = player.getKey(); JsonElement playerData = player.getValue(); // Use Gson to deserialize all fields except // for the name into a Node instance ... Node node = context.deserialize(playerData, Node.class); node.name = playerName; // ... then set the name. nodes.add(node); } return new Container(nodes); } } 

    假设一个像Container(List<Node>)这样的构造函数,并允许Container实例是不可变的,这通常是一件好事。

    注册并使用这样的自定义序列化程序:

     GsonBuilder builder = new GsonBuilder(); // Tell Gson to use the custom ContainerDeserializer whenever // it's asked for a Container instance. builder.registerTypeAdapter(Container.class, new ContainerDeserializer()); Gson gson = builder.create(); // Ask Gson to create Container instance from your JSON snippet. Container container = gson.fromJson(json, Container.class); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM