一个简单的JSON解析工具,可以匹配到相关的属性进行特殊化处理
前段时间,有个大数据的朋友找我帮忙,问我能不能在不转强类型对象的情况下,对json进行特殊化处理。我跟他说使用第三方json工具,如gson,fastjson等即可。后来他说希望灵活点,死代码不要太多,尽量通用性高。
于是乎,就有了这一套简单的json解析工具,虽然我目前用不上,可能大数据的程序员更加经常要处理json数据,而作为一个普通的Java程序员,基本上json只是用来作为数据传输的方式,很少会直接对json进行处理,一般是转成对应的强类型对象再进行业务处理。而即使要使用弱类型JSONObject,也不会做太多复杂的处理。
一、简单效果演示
调工具处理之后:
二、上代码
不多说,这里的功能比较简单
规则1:将日期格式改成yyyy-MM-dd
规则2:手机号码不满11位,特殊化处理
自己可以扩展出去定制化使用,基本上json的遍历是通用性的。后面的规则是自定义的。建议合理使用设计模式(如工厂模式),来合理把规则逻辑处理 扩展出去。
ps: 使用fastjson包的JSONObject进行json处理
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\": 0\n" +
" }\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));
}
}