简体   繁体   English

Gson使用泛型类型解析Json对象

[英]Gson parse a Json object with generic type

I have the following json written into a file which i want to read via Gson: 我将以下json写入我希望通过Gson阅读的文件中:

{
  "identifier": "CONFIG",
  "data": [
    {
      "identifier": "HOTKEY",
      "data": {
        "hotKey": "testKey1",
        "type": "APPLICATION",
        "runnableContext": "testContext1"
      }
    },
    {
      "identifier": "HOTKEY",
      "data": {
        "hotKey": "testKey2",
        "type": "APPLICATION",
        "runnableContext": "testContext2"
      }
    }
  ]
}

In the above Json, you can see that the Identifier & data construct is recursively repeated. 在上面的Json中,您可以看到标识符和数据结构是递归重复的。 So the basic class representing this repeated pattern is a generic one as shown below: 因此,表示此重复模式的基本类是通用的,如下所示:

{
  "identifier": "CONFIG",
  "data": {

  }
}

This pattern is represented by the JsonData class as follows: 此模式由JsonData类表示,如下所示:

import java.util.Set;

....
import com.google.common.collect.ImmutableSet;

/**
 * Class representing a simple {@link JsonData#identifier}, 
 * {@link JsonData#data}  format. This class can be used to 
 * persist application data for example in a Configuration file.
 * 
 * @author SW029693
 * @since v1.0
 */
public class JsonData <T>{
    /**
     * Represents a unique identifier 
     */
    private String identifier;
    /**
     * Represents the data pertaining to this {@link JsonData#identifier} 
     */
    private T data;

    private static final Set<String> VALID_JSON_ID_TYPES = ImmutableSet.of("CONFIG","HOTKEYS","HOTKEY","RECOMMENDATIONS");

    public JsonData(String identifier, T data) {
        super();
        this.identifier = identifier;
        this.data = data;
    }

    /**
     * Getter for {@link JsonData#identifier} 
     * @return
     */
    public String getIdentifier() {
        return identifier;
    }

    /**
     * Sets the {@link JsonData#identifier} to the given value
     * @param  identifier
     *         Represents a unique {@link JsonData#identifier}  
     * @throws VerifyException
     *         If the argument is {@code null} or {@code empty}
     */
    public void setIdentifier(String identifier) throws VerifyException{
        Verifier.verifyNotNull(identifier, "identifier : null");
        Verifier.verifyNotEmpty(identifier,"identifier : empty");
        this.identifier = identifier;
    }

    /**
     * Getter for {@link JsonData} 
     * @return
     */
    public T getData() {
        return data;
    }

    /**
     * Sets the {@link JsonData#data} to the given value
     * @param  identifier
     *         Represents a unique {@link JsonData#data}  
     * @throws VerifyException
     *         If the argument is {@code null} 
     */
    public void setData(T data) {
        Verifier.verifyNotNull(data, "data : null");
        this.data = data;
    }

    @Override
    public String toString() {
        return "JsonData [identifier=" + identifier + ", data=" + data + "]";
    }
}

Also, in the Json above, you can see that the data inside each hotkey. 另外,在上面的Json中,您可以看到每个热键内的数据。 This data is to be held in a ConfigurationProperty class after reading the json via gson: 在通过gson读取json之后,此数据将保存在ConfigurationProperty类中:

public class ConfigurationProperty implements Comparable<ConfigurationProperty>, Serializable{
....    
private final String hotKey;
private final String type;
private final String runnableContext;
....

Now the question. 现在的问题。 I am trying to read the file and parse the Json to store it into respective objects using GSON with no luck. 我正在尝试读取文件并解析Json以使用GSON将其存储到相应的对象中而没有运气。

I have some working code to read a single JsonData object written to the file: 我有一些工作代码来读取写入该文件的单个JsonData对象:

    {
      "identifier": "HOTKEY",
      "data": {
        "hotKey": "testKey1",
        "type": "APPLICATION",
        "runnableContext": "testContext1"
      }
    }

is succesfully read by: 成功阅读:

private static JsonData<ConfigurationProperty> readconfigFile() {
    Reader reader = null;
    JsonData<ConfigurationProperty> data = null;
    Gson gson  = null;
    Type confType;
    try {
        reader = new FileReader("./config.json");
        gson = new GsonBuilder().create();
        confType = new TypeToken<JsonData<ConfigurationProperty>>() {}.getType();

        data = gson.fromJson(reader,confType);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        fail("Test failed while reading the config.json file: "+e.getMessage());        }
    finally {
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
            fail("Test failed while reading the config.json file: "+e.getMessage());
        }
    }
    return data;
}

But if you look at the first json, this is now a recursive structure of JsonData. 但是如果你看第一个json,这现在是JsonData的递归结构。 Also while parsing, i need to tell Gson that the first data object is an ARRAY of JsonData objects. 同样在解析时,我需要告诉Gson第一个数据对象是JSONData对象的ARRAY。 And I also need to tell gson that each JSONData object in that array is of type ConfigurationProperty. 我还需要告诉gson该数组中的每个JSONData对象都是ConfigurationProperty类型。

I am not sure how to do this. 我不知道该怎么做。

I figured it out. 我想到了。 This is how I did it 这就是我做到的

    private static JsonData<List<ConfigurationProperty>> readconfigFileList() {
    Reader reader = null;
    JsonData<List<ConfigurationProperty>> dataArray = null;
    Gson gson  = null;
    Type confType;
    Type confTypeArray;
    try {
        reader = new FileReader("./config.json");
        gson = new GsonBuilder().create();
        confType = new TypeToken<JsonData<List<ConfigurationProperty>>>() {}.getType();

        dataArray = gson.fromJson(reader,confType);
        System.out.println(dataArray.toString());

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        fail("Test failed while reading the config.json file: "+e.getMessage());        }
    finally {
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
            fail("Test failed while reading the config.json file: "+e.getMessage());
        }
    }
    return dataArray;
}

Find the following code for generic Json object parsing OR Unknown Json object parsing using Gson library. 找到以下代码,用于通用Json对象解析或使用Gson库解析未知Json对象。

public class JsonParsing {

    static JsonParser parser = new JsonParser();

    public static HashMap<String, Object> createHashMapFromJsonString(String json) {

        JsonObject object = (JsonObject) parser.parse(json);
        Set<Map.Entry<String, JsonElement>> set = object.entrySet();
        Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
        HashMap<String, Object> map = new HashMap<String, Object>();

        while (iterator.hasNext()) {

            Map.Entry<String, JsonElement> entry = iterator.next();
            String key = entry.getKey();
            JsonElement value = entry.getValue();

            if (null != value) {
                if (!value.isJsonPrimitive()) {
                    if (value.isJsonObject()) {

                        map.put(key, createHashMapFromJsonString(value.toString()));
                    } else if (value.isJsonArray() && value.toString().contains(":")) {

                        List<HashMap<String, Object>> list = new ArrayList<>();
                        JsonArray array = value.getAsJsonArray();
                        if (null != array) {
                            for (JsonElement element : array) {
                                list.add(createHashMapFromJsonString(element.toString()));
                            }
                            map.put(key, list);
                        }
                    } else if (value.isJsonArray() && !value.toString().contains(":")) {
                        map.put(key, value.getAsJsonArray());
                    }
                } else {
                    map.put(key, value.getAsString());
                }
            }
        }
        return map;
    }
}

~Chandra 〜钱德拉

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

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