如将错误JSON字符串格式中的属性和属性值转化为集合中的键值对
一、JSON是如何表示的
JSON的定义请参考百度百科,官网为www.json.org。那么JSON是如何表示的。
例如:[{"id":"541407030131","name":"刘森","sex":"男","age":"23","class":"网络工程14-01","dormitory":"437","school":"郑州轻工业学院"}]
最外围是中括号,接着是花括号,属性和属性值均用双引号包裹,属性和属性值用冒号分隔。这里便于理解,我把属性和属性值称作属性键值对,属性键值对之间用逗号分隔。
二、一些错误的JSON表示方式
比如这样:[{id: "541407030131",name: "刘森",sex: "男",age: "23",class: "网络工程14-01",dormitory: "437",school: "郑州轻工业学院"}],属性键没有双引号包裹,属性键与冒号间有空格。
再比如这样[{ "id": "541407030131", "name": "刘森", "sex": "男", "age": "23", "class": "网络工程14-01", "dormitory": "437", "school": "郑州轻工业学院"}],属性键和属性值前有空格。
等等。
二、错误的JSON字符串格式的转换
我们的目的是对错误的JSON字符串中属性和属性值转化为集合中的键值对。下面以上一节中第一个错误的JSON表示方式为例,通过处理它来获取我们想要的结果。
1 package com.example.stringBuilder; 2 3 import java.util.HashMap; 4 import java.util.Iterator; 5 import java.util.Map; 6 7 /** 8 * created by 刘森 2018/7/24 18:06 9 * 获取错误的JSON格式字符串中的属性键值对 10 */ 11 public class RightJSON { 12 public static void main(String[] args) { 13 String wrongJSON = "[{id: \"541407030131\",name: \"刘森\",sex: \"男\",age: \"23\",class: \"网络工程14-01\"," + 14 "dormitory: \"437\",school: \"郑州轻工业学院\"}]"; 15 /*substring(a,b)中a索引参数是起点,b索引参数是终点,字符串中字符索引一般从左往右从0开始数, 16 截取后的字符串包括a但不包括b,所以我们从索引2开始去除去中括号和花括号。 17 */ 18 String bracket = wrongJSON.substring(2, wrongJSON.length() - 2); 19 //将字符串通过逗号分隔成字符串数组 20 String[] split = bracket.split(","); 21 //去空格。当我们遇到空格就将空格后字符截取出来 22 for (int k = 0; k < split.length; k++) { 23 if ((split[k].charAt(0) + "").equals(" ")) { 24 split[k] = split[k].substring(1); 25 } 26 } 27 //首先定义是split数组2倍长度的数组,用来存储属性键值对 28 String[] splitMap = new String[split.length * 2]; 29 for (int i = 0; i < split.length; i++) { 30 for (int j = 1; j < split[i].length(); j++) { 31 if ((split[i].charAt(j) + "").equals(":")) { 32 splitMap[i] = split[i].substring(0, j);//取前面部分 33 //System.out.println("前="+splitMap[i]); 34 //去掉冒号双引号,取中间值,注意j+3是把转义字符\也去掉 35 splitMap[i + split.length] = split[i].substring(j + 3, split[i].length() - 1); 36 //System.out.println("后="+splitMap[i+ split.length]); 37 } 38 } 39 40 } 41 //我们需要定义一个集合用于存储属性键值对 42 Map<String, Object> result = new HashMap<>(); 43 for (int i = 0; i < splitMap.length; i++) { 44 if (i == splitMap.length / 2) { 45 break; 46 } else { 47 result.put(splitMap[i], splitMap[i + splitMap.length / 2]); 48 } 49 } 50 //最后我们可以打印出属性键值对来检验是否达到我们的要求 51 Iterator it=result.entrySet().iterator(); 52 while(it.hasNext()){ 53 Map.Entry entry=(Map.Entry) it.next(); 54 System.out.println("key="+entry.getKey()+":"+"value="+entry.getValue()); 55 } 56 57 } 58 }
运行后的结果为
key=school:value=郑州轻工业学院
key=sex:value=男
key=dormitory:value=437
key=name:value=刘森
key=id:value=541407030131
key=class:value=网络工程14-01
key=age:value=23
这样的结果就符合我们的预期了。
四、总结
我们在实际开发过程中是使用工具类进行对数据进行处理的。原因:1、数据库中存储各种各样的不合法的JSON字符串格式,我们的方法并不具有适用性。也就是说,稍微添加个空格,程序就需要更改,很麻烦。
2、JSON是前后台交互的常用格式,但是存储格式会有所不同,所以数据库不同的非法JSON字符串格式也就见怪不怪了。
推荐使用阿里巴巴的JSON格式处理,导包如下。
com.alibaba.fastjson.JSON
例如:
List<Student> students = JSON.parseArray(wrongJSON, Student.class);
方法只接受String和类两个参数,返回的类型是自定义类型的集合。这样是不是在前后台JSON参数传递中方便了很多。这样深深地体会到站在巨人的肩膀上,可以看得更远。