在实际开发中,我们很容易会遇到一些 json 字符串,在不同的 json 中,相同的字段(或者说是属性)下会有不同的数据类型。如以下例子:
{
"group_by":[
{
"name": "time",
"group_count": "1",
"range_size": {
"value": "1",
"unit": "seconds"
}
},
{
"name": "value",
"range_size": "1"
}
]
}
在这个例子中,group_by
下是一个数列, 然而这个数列里的每一个值里都包含range_size
这个字段。在"name": "time"
所在的这个映射(字典)下的range_size
对应的值为一个映射(字典),而在"name": "value"
所在的这个映射(字典)下的range_size
对应的值为一个字符串。
private static String json = "{\"group_by\":["
+ "{\"name\": \"time\",\"group_count\": \"1\",\"range_size\": {\"value\": \"1\",\"unit\": \"seconds\"}},"
+ "{\"name\": \"value\",\"range_size\": \"1\"}]}";
public enum GroupByType {
TIME,
VALUE
}
public abstract class GroupBy {
private GroupByType type;
}
public class GroupByTime extends GroupBy {
@SerializedName("group_count")
private String groupCount;
@SerializedName("range_size")
private TimeUnit rangeSize;
public GroupByTime() {
super(GroupByType.TIME);
}
public void setRangeSize(String value, String unit) {
this.rangeSize = new TimeUnit();
rangeSize.setValue(value);
rangeSize.setUnit(unit);
}
@Override
public String toString() {
return "name: time\n"
+ "\tgroup_count: " + groupCount + "\n"
+ "\trange_size: " + rangeSize.getValue() + " " + rangeSize.getUnit();
}
class TimeUnit {
private String value;
private String unit;
}
}
public class GroupByValue extends GroupBy {
@SerializedName("range_size")
private String rangeSize;
public GroupByValue() {
super(GroupByType.VALUE);
}
@Override
public String toString() {
return "name: value\n"
+ "\trange_size: " + rangeSize;
}
}
ParseResult
public class ParseResult {
@SerializedName("group_by")
private List<GroupBy> groupBy;
public List<GroupBy> getGroupBy() {
if (groupBy == null)
groupBy = new LinkedList<>();
return groupBy;
}
public void addGroupBy(GroupBy groupBy) {
if (this.groupBy == null)
this.groupBy = new LinkedList<>();
this.groupBy.add(groupBy);
}
}
public class GroupByDeserializer implements JsonDeserializer<ParseResult> {
@Override
public ParseResult deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonArray jsonArray = jsonElement.getAsJsonObject().get("group_by").getAsJsonArray();
Map<String, GroupByType> mapping = new HashMap<>();
mapping.put("time", GroupByType.TIME);
mapping.put("value", GroupByType.VALUE);
ParseResult result = new ParseResult();
for (JsonElement element : jsonArray) {
JsonObject jsonObject = element.getAsJsonObject();
switch (mapping.get(jsonObject.get("name").getAsString())) {
case TIME:
GroupByTime groupByTime = new GroupByTime();
groupByTime.setGroupCount(jsonObject.get("group_count").getAsString());
JsonObject temp = jsonObject.getAsJsonObject("range_size");
groupByTime.setRangeSize(temp.get("value").getAsString(), temp.get("unit").getAsString());
result.addGroupBy(groupByTime);
break;
case VALUE:
GroupByValue groupByValue = new GroupByValue();
groupByValue.setRangeSize(jsonObject.get("range_size").getAsString());
result.addGroupBy(groupByValue);
break;
default:
break;
}
}
return result;
}
}
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(ParseResult.class, new GroupByDeserializer());
Gson gson = gsonBuilder.create();
ParseResult result = gson.fromJson(json, ParseResult.class);
System.out.println("Method 1 ==============================================");
result.getGroupBy().forEach(System.out::println);
System.out.println("=======================================================\n\n\n");
Method 1 ==============================================
name: time
group_count: 1
range_size: 1 seconds
name: value
range_size: 1
=======================================================
相信看到这里的大家都不可能不知道什么是DOM了,不过不知道也不影响我们接下来的实现,不过我还是强烈推荐各位读者,一定要去学习。
另外,这种方法比较简单,就不加过多的解释了,直接上代码吧。
public class PrimitiveParser {
private final String jsonStr;
private Map<String, GroupByType> mapping;
public PrimitiveParser(String jsonStr) {
this.jsonStr = jsonStr;
mapping = new HashMap<>();
mapping.put("time", GroupByType.TIME);
mapping.put("value", GroupByType.VALUE);
}
public List<GroupBy> parse() {
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(jsonStr).getAsJsonObject();
JsonArray array = obj.getAsJsonArray("group_by");
List<GroupBy> list = new LinkedList<>();
for (JsonElement element : array) {
JsonObject jsonObject = element.getAsJsonObject();
switch (mapping.get(jsonObject.get("name").getAsString())) {
case TIME:
GroupByTime groupByTime = new GroupByTime();
groupByTime.setGroupCount(jsonObject.get("group_count").getAsString());
JsonObject temp = jsonObject.getAsJsonObject("range_size");
groupByTime.setRangeSize(temp.get("value").getAsString(), temp.get("unit").getAsString());
list.add(groupByTime);
break;
case VALUE:
GroupByValue groupByValue = new GroupByValue();
groupByValue.setRangeSize(jsonObject.get("range_size").getAsString());
list.add(groupByValue);
break;
default:
break;
}
}
return list;
}
}
PrimitiveParser parser = new PrimitiveParser(json);
List<GroupBy> list = parser.parse();
System.out.println("Method 2 ==============================================");
list.forEach(System.out::println);
System.out.println("=======================================================\n\n\n");
Method 2 ==============================================
name: time
group_count: 1
range_size: 1 seconds
name: value
range_size: 1
=======================================================
相关的代码我已上传CSDN,有需要的兄弟们可以直接去下载
https://download.csdn.net/download/zifung_yip/11099832