JSON解析之树模型思想
- JSON解析
- 如何解析JSON
- 接下来将用到的方法简述
- 实战
- 问题描述
- 解析需求
- 解析结果
- 代码实现
- 创建实体类
- 核心解析代码
- 运行结果
- 总结
JSON解析
常见解析器
- Jsonlib(官方Json接口实现的实现类)
- Gson(谷歌)
- fastjson(阿里巴巴)
- jackson(Spring MVC 框架内置的解析器)
基本使用
- 添加jackson的相关依赖/导入jackson的相关jar包
- 创建Jackson核心对象 ObjectMapper
- 调用ObjectMapper的相关方法进行转换
无论是序列化还是反序列化,Jackson都提供了三种方式
- JSON <–> Java Object (对象绑定,也是我们用得最多的)
- JSON <–> JsonNode Tree(类似于XML的DOM树)
- JSON <–> Json Stream (这是一个低层次的api,很强大,但是比较繁琐)
如何解析JSON
尽管有很多种拆分JSON并解析的方法,但是可以归纳成3种:
- 迭代:对事件流(Jackson称之为Token流)的迭代
- 数据绑定:将Json数据绑定到对象
- 遍历树:构建一个树结构并使用合适的方法遍历它
接下来将用到的方法简述
- public JsonNode readTree(String var1)
Jackson提供一个树节点被称为"JsonNode",我将其称之为该json树的根节点对象 - public JsonNode get(String var1)
根据键名,返回JsonNode节点对象 - public String asText()
有值返回值,无值返回空字符串
实战
问题描述
[{
"object": [{
"content": 103,
"name": "编码",
"code": "code"
}, {
"content": "经理层(部门)",
"name": "名称",
"code": "name"
}, {
"content": "0001A110000000002D15",
"name": "上级部门",
"code": "pk_fatherorg"
}, {
"content": 10,
"name": "上级业务单元编码",
"code": "fatherorg_code"
}, {
"content": "中南控股集团有限公司",
"name": "上级业务单元名称",
"code": "fatherorg_name"
}, {
"content": "中南集团",
"name": "所属集团名称",
"code": "group_name"
}, {
"content": "1001B210000000EQ6D5U",
"name": "组织主键",
"code": "pk_org"
}, {
"content": 0,
"name": "删除标志",
"code": "dr"
}, {
"content": "2020-01-02 11:26:25",
"name": "时间戳",
"code": "ts"
}, {
"content": "Y",
"name": "是否生效状态",
"code": "iseffect"
}, {
"content": "控股",
"name": "所属产业",
"code": "corp"
}]
}, {
"object": [{
"content": 102,
"name": "编码",
"code": "code"
}, {
"content": "董事会(部门)",
"name": "名称",
"code": "name"
}, {
"content": "0001A110000000002D15",
"name": "上级部门",
"code": "pk_fatherorg"
}, {
"content": 10,
"name": "上级业务单元编码",
"code": "fatherorg_code"
}, {
"content": "中南控股集团有限公司",
"name": "上级业务单元名称",
"code": "fatherorg_name"
}, {
"content": "中南集团",
"name": "所属集团名称",
"code": "group_name"
}, {
"content": "1001B210000000EQ6D61",
"name": "组织主键",
"code": "pk_org"
}, {
"content": 0,
"name": "删除标志",
"code": "dr"
}, {
"content": "2018-11-21 09:06:00",
"name": "时间戳",
"code": "ts"
}, {
"content": "Y",
"name": "是否生效状态",
"code": "iseffect"
}, {
"content": "控股",
"name": "所属产业",
"code": "corp"
}]
}]
解析需求
解析结果
[{
"code":103,"name":"经理层(部门)",
"pk_fatherorg":"0001A110000000002D15",
"fatherorg_code":10,"fatherorg_name":"中南控股集团有限公司",
"group_name":"中南集团","pk_org":"1001B210000000EQ6D5U",
"dr":0,
"ts":"2020-01-02 11:26:25","iseffect":"Y","corp":"控股"
},
{
"code":102,
"name":"董事会(部门)",
"pk_fatherorg":"0001A110000000002D15",
"fatherorg_code":10,
"fatherorg_name":"中南控股集团有限公司",
"group_name":"中南集团",
"pk_org":"1001B210000000EQ6D61",
"dr":0,
"ts":"2018-11-21 09:06:00",
"iseffect":"Y","corp":"控股"
}]
代码实现
创建实体类
/**
* @author Mitchell
* @Description
* @create 2020-04-04 19:21
*/
public class CustomObject {
private Integer code;
private String name;
private String pk_fatherorg;
private Integer fatherorg_code;
private String fatherorg_name;
private String group_name;
private String pk_org;
private Integer dr;
private String ts;
private String iseffect;
private String corp;
........(省略getter setter toString() 构造方法)
核心解析代码
/**
* @author Mitchell
* @Description 使用Jackson工具解析JSON的优化。使用DOM文档对象模型的思想。
* @create 2020-04-04 19:34
*/
public class JacksonOptimizing {
/**
* 对象容器,存解析结果
*/
private static List<CustomObject> customObjectList = new ArrayList<>();
public static void main(String[] args) throws IOException {
String json = "[{\n" +
" \"object\": [{\n" +
" \"content\": 103,\n" +
" \"name\": \"编码\",\n" +
" \"code\": \"code\"\n" +
" }, {\n" +
" \"content\": \"经理层(部门)\",\n" +
" \"name\": \"名称\",\n" +
" \"code\": \"name\"\n" +
" }, {\n" +
" \"content\": \"0001A110000000002D15\",\n" +
" \"name\": \"上级部门\",\n" +
" \"code\": \"pk_fatherorg\"\n" +
" }, {\n" +
" \"content\": 10,\n" +
" \"name\": \"上级业务单元编码\",\n" +
" \"code\": \"fatherorg_code\"\n" +
" }, {\n" +
" \"content\": \"中南控股集团有限公司\",\n" +
" \"name\": \"上级业务单元名称\",\n" +
" \"code\": \"fatherorg_name\"\n" +
" }, {\n" +
" \"content\": \"中南集团\",\n" +
" \"name\": \"所属集团名称\",\n" +
" \"code\": \"group_name\"\n" +
" }, {\n" +
" \"content\": \"1001B210000000EQ6D5U\",\n" +
" \"name\": \"组织主键\",\n" +
" \"code\": \"pk_org\"\n" +
" }, {\n" +
" \"content\": 0,\n" +
" \"name\": \"删除标志\",\n" +
" \"code\": \"dr\"\n" +
" }, {\n" +
" \"content\": \"2020-01-02 11:26:25\",\n" +
" \"name\": \"时间戳\",\n" +
" \"code\": \"ts\"\n" +
" }, {\n" +
" \"content\": \"Y\",\n" +
" \"name\": \"是否生效状态\",\n" +
" \"code\": \"iseffect\"\n" +
" }, {\n" +
" \"content\": \"控股\",\n" +
" \"name\": \"所属产业\",\n" +
" \"code\": \"corp\"\n" +
" }]\n" +
"}, {\n" +
" \"object\": [{\n" +
" \"content\": 102,\n" +
" \"name\": \"编码\",\n" +
" \"code\": \"code\"\n" +
" }, {\n" +
" \"content\": \"董事会(部门)\",\n" +
" \"name\": \"名称\",\n" +
" \"code\": \"name\"\n" +
" }, {\n" +
" \"content\": \"0001A110000000002D15\",\n" +
" \"name\": \"上级部门\",\n" +
" \"code\": \"pk_fatherorg\"\n" +
" }, {\n" +
" \"content\": 10,\n" +
" \"name\": \"上级业务单元编码\",\n" +
" \"code\": \"fatherorg_code\"\n" +
" }, {\n" +
" \"content\": \"中南控股集团有限公司\",\n" +
" \"name\": \"上级业务单元名称\",\n" +
" \"code\": \"fatherorg_name\"\n" +
" }, {\n" +
" \"content\": \"中南集团\",\n" +
" \"name\": \"所属集团名称\",\n" +
" \"code\": \"group_name\"\n" +
" }, {\n" +
" \"content\": \"1001B210000000EQ6D61\",\n" +
" \"name\": \"组织主键\",\n" +
" \"code\": \"pk_org\"\n" +
" }, {\n" +
" \"content\": 0,\n" +
" \"name\": \"删除标志\",\n" +
" \"code\": \"dr\"\n" +
" }, {\n" +
" \"content\": \"2018-11-21 09:06:00\",\n" +
" \"name\": \"时间戳\",\n" +
" \"code\": \"ts\"\n" +
" }, {\n" +
" \"content\": \"Y\",\n" +
" \"name\": \"是否生效状态\",\n" +
" \"code\": \"iseffect\"\n" +
" }, {\n" +
" \"content\": \"控股\",\n" +
" \"name\": \"所属产业\",\n" +
" \"code\": \"corp\"\n" +
" }]\n" +
"}]\n";
//实体类
CustomObject customObject = null;
//调用解析方法
parse(customObjectList, customObject, json);
//解析完成
customObjectList.forEach(System.out::println);
}
/**
* JSON解析方法
*
* @param customObject
* @param customObject
* @param json
*/
private static void parse(List<CustomObject> customObjectList, CustomObject customObject, String json) throws IOException {
//创建Jackson的核心对象 ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
//读取JSON树结构,获得根节点对象
JsonNode jsonNodeRoot = objectMapper.readTree(json);
//遍历根节点下的直接子节点
for (int i = 0; i < jsonNodeRoot.size(); i++) {
customObject = new CustomObject();
//获得键名为object的节点
JsonNode jsonNodeObject = jsonNodeRoot.get(i).get("object");
for (int j = 0; j < jsonNodeObject.size(); j++) {
String code = jsonNodeObject.get(j).get("code").asText();
switch (code) {
case "code":
customObject.setCode(Integer.parseInt(getPropertyValue(jsonNodeObject, j)));
break;
case "name":
customObject.setName(getPropertyValue(jsonNodeObject, j));
break;
case "pk_fatherorg":
customObject.setPk_fatherorg(getPropertyValue(jsonNodeObject, j));
break;
case "fatherorg_code":
customObject.setFatherorg_code(Integer.parseInt(getPropertyValue(jsonNodeObject, j)));
break;
case "fatherorg_name":
customObject.setFatherorg_name(getPropertyValue(jsonNodeObject, j));
break;
case "group_name":
customObject.setGroup_name(getPropertyValue(jsonNodeObject, j));
case "pk_org":
customObject.setPk_org(getPropertyValue(jsonNodeObject, j));
break;
case "dr":
customObject.setDr(Integer.parseInt(getPropertyValue(jsonNodeObject, j)));
break;
case "ts":
customObject.setTs(getPropertyValue(jsonNodeObject, j));
break;
case "iseffect":
customObject.setIseffect(getPropertyValue(jsonNodeObject, j));
break;
case "corp":
customObject.setCorp(getPropertyValue(jsonNodeObject, j));
break;
}
}
//将对象添加入集合中
customObjectList.add(customObject);
}
}
/**
* 通过节点对象和遍历次数来获得,键名为“content”的值
*
* @param jsonNodeObject
* @param j
* @return String
*/
private static String getPropertyValue(JsonNode jsonNodeObject, int j) {
return jsonNodeObject.get(j).get("content").asText();
}
}
运行结果
总结
- Databinding(数据绑定)是最常用的json处理方式,生成json时,创建相关的java对象,并根据json内容结构把java对象组装起来。
解析时,直接把json映射到相关的java对象,遍历java对象即可取值。 - TreeModel处理json,是以树型结构来生成和解析json,生成json时,根据json内容结构,创建不同类型的节点对象,组装这些节点生成json。解析json时,不需要绑定json到java bean,根据json结构,找到所需的节点,使用path或get方法查找内容。