一个简单的JSON解析工具,可以匹配到相关的属性进行特殊化处理
前段时间,有个大数据的朋友找我帮忙,问我能不能在不转强类型对象的情况下,对json进行特殊化处理。我跟他说使用第三方json工具,如gson,fastjson等即可。后来他说希望灵活点,死代码不要太多,尽量通用性高。
于是乎,就有了这一套简单的json解析工具,虽然我目前用不上,可能大数据的程序员更加经常要处理json数据,而作为一个普通的Java程序员,基本上json只是用来作为数据传输的方式,很少会直接对json进行处理,一般是转成对应的强类型对象再进行业务处理。而即使要使用弱类型JSONObject,也不会做太多复杂的处理。
一、简单效果演示
调工具处理之后:
二、上代码
不多说,这里的功能比较简单
规则1:将日期格式改成yyyy-MM-dd 规则2:手机号码不满11位,特殊化处理
自己可以扩展出去定制化使用,基本上json的遍历是通用性的。后面的规则是自定义的。建议合理使用设计模式(如工厂模式),来合理把规则逻辑处理 扩展出去。
ps: 使用fastjson包的JSONObject进行json处理
代码语言:javascript复制public class demo {
public static void main(String[] args) {
String json = "{n"
" "code": 0,n"
" "data": {n"
" "created_time": "2019-12-05 23:58:41",n"
" "identity_code": "",n"
" "channel_src": "",n"
" "task_data": {n"
" "education_info": {n"
" "college_info": [n"
" {n"
" "college_graduation": "",n"
" "college_name": ""n"
" }n"
" ],n"
" "highschool_info": [n"
" {n"
" "highschool_graduation": "",n"
" "highschool_name": ""n"
" }n"
" ]n"
" },n"
" "publish_info": [n"
" {n"
" "site": "",n"
" "page_time": "",n"
" "nickname": "",n"
" "likenames": [n"
" "111",n"
" "222"n"
" ],n"
" "commentsnum": 0,n"
" "likenum": 0n"
" }n"
" ],n"
" "base_info": [n"
" {n"
" "nickname": "A",n"
" "religion_trend": "A",n"
" "mobilephones": [n"
" "13112341234",n"
" "131111111"n"
" ]n"
" t},n"
" {n"
" "nickname": "B",n"
" "religion_trend": "B",n"
" "mobilephones": [n"
" "13112341234",n"
" "13112341234",n"
" "10086"n"
" ]n"
" t}n"
" ]n"
" },n"
" "user_mobile": "",n"
" "user_name": "",n"
" "real_name": "",n"
" "channel_code": "103001",n"
" "channel_attr": "",n"
" "channel_type": "SOCIAL"n"
" },n"
" "task_id": "TASKSOCIAL103001201912052358410321541243",n"
" "message": "success"n"
"}";
// 用json创建JSONObject对象
JSONObject jsonObject = JSONObject.parseObject(json);
System.out.println(jsonObject.toJSONString());
doJson(jsonObject, "data.created_time", 1);
doJson(jsonObject, "data.task_data.base_info.mobilephones", 2);
System.out.println("更新后的json串:n" jsonObject "n");
}
/**
* 匹配json
*/
private static void doJson(JSONObject jsonObject, String path, int rule) {
int index = path.indexOf('.');
if (index < 0) {
// 递归的出口
String key = path;
try {
// 规则逻辑处理,建议用工厂模式 or 策略模式 扩展出去
switch (rule) {
case 1:
// 处理日期
doRule1(jsonObject, key);
break;
case 2:
// 处理长度
doRule2(jsonObject, key);
break;
default:
}
} catch (Exception e) {
// 建议在处理具体的值时候,用try catch隔离开。让他不要影响到其他值的变更。
// 或者说,如果你觉得,有一个值设置失败了,其他值也别搞了,那可以直接让他外抛异常
e.printStackTrace();
}
return;
}
String prePath = path.substring(0, index);
String nextPath = path.substring(index 1);
Object valueObj = jsonObject.get(prePath);
if (null == valueObj) {
throw new RuntimeException(String.format("路径有误:%s", path));
}
if (valueObj instanceof JSONObject) {
// 对象类型
doJson((JSONObject)valueObj, nextPath, rule);
}
else if (valueObj instanceof JSONArray) {
// 数组类型
JSONArray array = (JSONArray)valueObj;
if (null != array && !array.isEmpty()) {
for (int i = 0; i < array.size(); i ) {
doJson(array.getJSONObject(i), nextPath, rule);
}
}
}
else {
throw new RuntimeException(String.format("路径有误:%s 当前key:%s 对应的是基础类型 %s,不能再往下走", path, prePath, valueObj.toString()));
}
}
/**
* 规则1
*/
private static void doRule1(JSONObject jsonObject, String key) {
String beforeDateStr = jsonObject.getString(key);
System.out.println("原值:" beforeDateStr);
jsonObject.put(key, beforeDateStr.substring(0, beforeDateStr.indexOf(' ')));
System.out.println("新值:" jsonObject.getString(key));
}
/**
* 规则2
*/
private static void doRule2(JSONObject jsonObject, String key) {
System.out.println("更新前:" jsonObject.getString(key));
List<String> list = JSONObject.parseArray(jsonObject.getString(key), String.class);
if (null != list && !list.isEmpty()) {
for (int i = 0; i < list.size(); i ) {
String beforeStr = list.get(i);
if (beforeStr.length() != 11) {
beforeStr = "给你个默认值";
list.set(i, beforeStr);
}
}
jsonObject.put(key, list);
}
System.out.println("更新后:" jsonObject.getString(key));
}
}