[英]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.