JSON动态解析
- 问题的由来
在公司实习期间,遇到了这样一个问题,就是动态去请求不同的API接口,去解析返回的JSON数据,并且得存储到数据库中。在知道json返回的数据类型,然后创建对应的pojo类,去解析json这样的我们都容易操作,但是在不知道json返回数据字段情况下,如何实现动态解析并动态建表存储,这个就难到我了。后面在挣扎了好久,终于找到了解决的办法,现在就做个总结。
首先来看一下几种类型的json数据
- 比较常见的 ,普通类型
{ "rtnCode": "000000", "rtnMsg": "success", "data": { "name": "张丽花", "gender": "女",1 "spell": " ", 1 "birthday": "1985-05-16", 1 "idCard": "352202198505XXXX",1 "validDate": "",1 "guideNum": "D-3522-001332",1 "qualificationCode": "DZG2006JX12296", "randAndLanguage": " 普通话--初级 ", "nation": "汉族",1 "tel": "13459300151", "organization": "宁德市旅游协会导游工作部门", "touristAdministration": "宁德市旅游发展委员会", "photo_front": "http://ossdev.12301e.com/upload_a137919f030f8458761d202c468f2c2c.jpg",1 "photo_reverse": "http://ossdev.12301e.com/upload_f94f8ca17c9078a82180e4f99b4ce854.jpg",1 "photo": "http://ossdev.12301e.com/upload_d790b665898f74c39e8515e645857d3a.jpg",1 "result": "通过",1 "approver": "关艳苹", 1 "company": "宁德市旅游发展委员会" } }
- 复杂一点的,含有list的多条数据
{ "rtnCode": "000000", "rtnMsg": "success", "data": { "totalPage": "1", "totalSize": "1", "list": [ { "name": "张丽花", "idCard": "352202198505XXXX", "guideNum": "D-3522-001332", "gender": "女", "rank": "初级", "date": "2017-12-08", "approver": "关艳苹", "id": "1886351" }, { "name": "张丽花2", "idCard": "3522021985051XXXX", "guideNum": "D-3522-001332", "gender": "女", "rank": "初级", "date": "2017-12-08", "approver": "关艳苹", "id": "1886351" },{ "name": "张丽花3", "idCard": "3522021985XXXX", "guideNum": "D-3522-001332", "gender": "女", "rank": "初级", "date": "2017-12-08", "approver": "关艳苹", "id": "1886351" } ] } }
接下来,我们就要去实现解析这两种类型的json数据。
这里我提供了一个工具类,专门用来解析json字符串
import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /* * JsonUtils生成json数据和解析json数据 */ public class JsonUtils { static ObjectMapper objectMapper; /* * Json字符串转 Object对象 */ public static <T> T fromJson(String content, Class<T> valueType) { if (objectMapper == null) { objectMapper = new ObjectMapper(); } try { return objectMapper.readValue(content, valueType); } catch (Exception e) { e.printStackTrace(); } return null; } /* * Object对象转 json字符串 */ public static String toJson(Object object) { if (objectMapper == null) { objectMapper = new ObjectMapper(); } try { return objectMapper.writeValueAsString(object); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json格式的字符串解析成Map对象 json格式:{"name":"admin","retries":"3fff"} * * @param object * @return */ public Map<String, String> jsonToMap(Object object) { Map<String, String> data = new HashMap<String, String>(); try { if(object!=null&&!object.equals("")){ // 将json字符串转换成jsonObject JSONObject jsonObject = JSONObject.fromObject(object); Iterator<?> it = jsonObject.keys(); // 遍历jsonObject数据,添加到Map对象 while (it.hasNext()) { String key = String.valueOf(it.next()); String value = (String) jsonObject.get(key).toString(); data.put(key, value); } } } catch (Exception e) { e.printStackTrace(); } return data; } /** * 将json格式的字符串解析成List-Map对象 * json格式:[{"name":"admin","retries":"3fff"},{"name":"admin","retries": * "3fff"}] * * @param object * @return */ public List<Map<String, String>> jsonToList(Object object) { JSONArray arry = JSONArray.fromObject(object); List<Map<String, String>> rsList = new ArrayList<Map<String, String>>(); for (int i = 0; i < arry.size(); i++) { JSONObject jsonObject = arry.getJSONObject(i); Map<String, String> map = new HashMap<String, String>(); for (Iterator<?> iter = jsonObject.keys(); iter.hasNext();) { String key = (String) iter.next(); String value = null; if(jsonObject.get(key)!=null){ value = jsonObject.get(key).toString(); }else{ value = ""; } map.put(key, value); } rsList.add(map); } return rsList; } }
使用的时候需要用到下面几个jar包,可自行百度下载,如有需要也可联系我邮箱发送:
注意commons-collections使用3点几版本的,不要太高,不然会报错
测试工具类得使用
import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.hrt.json.JsonUtils; import com.hrt.service.DyinfoService; import net.sf.json.JSONObject; @Service public class TestJson { @Autowired DyinfoService dyinfoService; public static void main(String[] args) { String str1="{\r\n" + " \"rtnCode\": \"000000\",\r\n" + " \"rtnMsg\": \"success\",\r\n" + " \"data\": {\r\n" + " \"totalPage\": \"1\",\r\n" + " \"totalSize\": \"1\",\r\n" + " \"list\": [\r\n" + " {\r\n" + " \"name\": \"张丽花\",\r\n" + " \"idCard\": \"352202198505XXXX\",\r\n" + " \"guideNum\": \"D-3522-001332\",\r\n" + " \"gender\": \"女\",\r\n" + " \"rank\": \"初级\",\r\n" + " \"date\": \"2017-12-08\",\r\n" + " \"approver\": \"关艳苹\",\r\n" + " \"id\": \"1886351\"\r\n" + " }\r\n" + " ]\r\n" + " }\r\n" + "}"; String str2="{\r\n" + " \"rtnCode\": \"000000\",\r\n" + " \"rtnMsg\": \"success\",\r\n" + " \"data\": {\r\n" + " \"name\": \"张丽花\",\r\n" + " \"gender\": \"女\",\r\n" + " \"spell\": \" \",\r\n" + " \"birthday\": \"1985-05-16\",\r\n" + " \"idCard\": \"352202198505XXXX\",\r\n" + " \"validDate\": \"\",\r\n" + " \"guideNum\": \"D-3522-001332\",\r\n" + " \"qualificationCode\": \"DZG2006JX12296\",\r\n" + " \"randAndLanguage\": \" 普通话--初级 \",\r\n" + " \"nation\": \"汉族\",\r\n" + " \"tel\": \"13459300151\",\r\n" + " \"organization\": \"宁德市旅游协会导游工作部门\",\r\n" + " \"touristAdministration\": \"宁德市旅游发展委员会\",\r\n" + " \"photo_front\": \"http://ossdev.12301e.com/upload_a137919f030f8458761d202c468f2c2c.jpg\",\r\n" + " \"photo_reverse\": \"http://ossdev.12301e.com/upload_f94f8ca17c9078a82180e4f99b4ce854.jpg\",\r\n" + " \"photo\": \"http://ossdev.12301e.com/upload_d790b665898f74c39e8515e645857d3a.jpg\",\r\n" + " \"result\": \"通过\",\r\n" + " \"approver\": \"关艳苹\",\r\n" + " \"company\": \"宁德市旅游发展委员会\"\r\n" + " }\r\n" + "}"; String str3="{\r\n" + " \"rtnCode\": \"000000\",\r\n" + " \"rtnMsg\": \"success\",\r\n" + " \"data\": {\r\n" + " \"totalPage\": \"1\",\r\n" + " \"totalSize\": \"1\",\r\n" + " \"list\": [\r\n" + " {\r\n" + " \"name\": \"张丽花\",\r\n" + " \"idCard\": \"35220219850516XXXX\",\r\n" + " \"guideNum\": \"D-3522-001332\",\r\n" + " \"gender\": \"女\",\r\n" + " \"rank\": \"初级\",\r\n" + " \"date\": \"2017-12-08\",\r\n" + " \"approver\": \"关艳苹\",\r\n" + " \"id\": \"1886351\"\r\n" + " }, {\r\n" + " \"name\": \"张丽花2\",\r\n" + " \"idCard\": \"352202198505XXXX\",\r\n" + " \"guideNum\": \"D-3522-001332\",\r\n" + " \"gender\": \"女\",\r\n" + " \"rank\": \"初级\",\r\n" + " \"date\": \"2017-12-08\",\r\n" + " \"approver\": \"关艳苹\",\r\n" + " \"id\": \"1886351\"\r\n" + " }\r\n" + " ]\r\n" + " }\r\n" + "}"; String str4="{ \r\n" + " \"rtnCode\":\"000000\", \r\n" + " \"rtnMsg\":\"success\", \r\n" + " \"data\":{ \r\n" + " \"id\":\"984DAFA4B837457A86896FCE40DA187D\", \r\n" + " \"fzsaqscjdglj\":\"福州市安全生产监督管理局\", \r\n" + " \"list\":[ \r\n" + " { \r\n" + " \"id\":\"4695DB12B22D4944AE509990B0288175\", \r\n" + " \"fzsaqscjdglj\":\"鼓楼区安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"1B00C5F841134E1FBBFAE43DCA0AD6AE\", \r\n" + " \"fzsaqscjdglj\":\"台江区安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"4F609BE00DD049E9B67E8127FD4AAAB1\", \r\n" + " \"fzsaqscjdglj\":\"仓山区安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"6AC3975D50EA42158AA6C956DDF71D8D\", \r\n" + " \"fzsaqscjdglj\":\"马尾区安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"BE6142BAF13D42B08C41C53AEDBE97FB\", \r\n" + " \"fzsaqscjdglj\":\"晋安区安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"60924D35DE324BC5BE7EF7A7BD1C7E9B\", \r\n" + " \"fzsaqscjdglj\":\"闽侯县安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"8FE3B90CB6B34248A4EA7CCD740923E7\", \r\n" + " \"fzsaqscjdglj\":\"连江县安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"DD72643D8B55428EBDA686F186011016\", \r\n" + " \"fzsaqscjdglj\":\"罗源县安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"5014816A8D0E445DBEF144F986436C21\", \r\n" + " \"fzsaqscjdglj\":\"闽清县安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"2FE491E25E7B46408DF5A9036BAADDBD\", \r\n" + " \"fzsaqscjdglj\":\"永泰县安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"B8AF0FB8F1C84EFBADBF5CD353A3C175\", \r\n" + " \"fzsaqscjdglj\":\"福清市安全生产监督管理局\" \r\n" + " }, \r\n" + " { \r\n" + " \"id\":\"D7EE9BD5365343EE83A4BDD55C55E2BB\", \r\n" + " \"fzsaqscjdglj\":\"长乐市安全生产监督管理局\" \r\n" + " } \r\n" + " ] \r\n" + " } \r\n" + "}"; toJson(str3); } //json解析 public static void toJson(String str) { JsonUtils t=new JsonUtils(); //1。首先解析成一个map集合###并遍历输出含有字段及字段对应的值 key-value System.out.println("第1:首先解析成一个map集合并遍历输出含有的字段"); Map<String,String> p1= t.jsonToMap(str); Set<String> keys=p1.keySet(); //获取map集合内所有字段 for(String a:keys) { System.out.println("key:"+a+" ,value:"+p1.get(a)); } //2. 获取data数据,及获取map集合内的data字段,再解析###data内字段 System.out.println("第2: 获取data数据,及获取map集合内的data字段,再解析data内字段"); String data2= p1.get("data"); //获取到data内的内容 Map<String,String> p2= t.jsonToMap(data2); //将data内的内容转map集合 Set<String> keys2=p2.keySet();获取data内所有字段 for(String a:keys2) { System.out.println("key:"+a+" ,value:"+p2.get(a)); } //普通的解析,用到1,2 就可以了 //第3.解析list,获取到p2里的list字段的value,然后转换为 List<Map<key,value>> ,这里的list字段得提供 System.out.println("第3:.解析list,获取到p2里的list字段的value,然后转换为 List<Map<key,value>>"); if(p2.containsKey("list")) { //判断是否含有list字段 String list= p2.get("list"); //获取到data内的内容 List<Map<String, String>> p3= t.jsonToList(list); //调用工具类方法,然后转换为 List<Map<key,value>> for(int i=0;i<p3.size();i++) { //遍历输出 Map<String,String> m3= p3.get(i); //遍历list内的map Set<String> keys3=m3.keySet();获取map内的对象所有字段 for(String a:keys3) { System.out.println("key:"+a+" ,value:"+m3.get(a)); } } } } }
解析结果如下:
第1:首先解析成一个map集合###并遍历输出含有的字段 key:data ,value:{"totalPage":"1","totalSize":"1","list":[{"name":"张丽花","idCard":"3522021985051XXXX","guideNum":"D-3522-001332","gender":"女","rank":"初级","date":"2017-12-08","approver":"关艳苹","id":"1886351"},{"name":"张丽花2","idCard":"3522021985051XXXX","guideNum":"D-3522-001332","gender":"女","rank":"初级","date":"2017-12-08","approver":"关艳苹","id":"1886351"}]} key:rtnMsg ,value:success key:rtnCode ,value:000000 第2: 获取data数据,及获取map集合内的data字段,再解析###data内字段 key:totalSize ,value:1 key:totalPage ,value:1 key:list ,value:[{"name":"张丽花","idCard":"35220219850516XXXX","guideNum":"D-3522-001332","gender":"女","rank":"初级","date":"2017-12-08","approver":"关艳苹","id":"1886351"},{"name":"张丽花2","idCard":"352202198505XXXX","guideNum":"D-3522-001332","gender":"女","rank":"初级","date":"2017-12-08","approver":"关艳苹","id":"1886351"}] 第3:.解析list,获取到p2里的list字段的value,然后转换为 List<Map<key,value>> key:date ,value:2017-12-08 key:approver ,value:关艳苹 key:gender ,value:女 key:guideNum ,value:D-3522-001332 key:idCard ,value:3522021985051XXXX key:name ,value:张丽花 key:rank ,value:初级 key:id ,value:1886351 key:date ,value:2017-12-08 key:approver ,value:关艳苹 key:gender ,value:女 key:guideNum ,value:D-3522-001332 key:idCard ,value:352202198XXXX key:name ,value:张丽花2 key:rank ,value:初级 key:id ,value:1886351
解析字段完成了,接下来就是对应着去实现动态建表的方法及存储的方法。
有兴趣的老爷,可以关注我的公众号【一起收破烂】,回复【006】获取2021最新java面试资料以及简历模型120套哦~