业务场景:
接收String 串(指定个的格式),解析成JSON串,然后对需要转码的字段做转码操作,然后toString 转发出去
例:
String str = "{ "msgBody":{"name":"",
"age":"",
"sex":"",
"grilsFriends":[{
"name":"",
"age":"",
"height": "",
"hobby":[{
"seeTV":"",
"eat": [{ "food":"" , "Fruits":"","drink" :""}],
"shopping":[{ "clothes":[{ "brand":"","waist":"" }],
"Cosmetics":[{ "rouge":"","brand":""}],
"packages":[{"brand":"","handbag":""}]
}] },{
"seeTV":"",
"eat": [{ "food":"" , "Fruits":"","drink" :""}]
}]
}],
"friends":[{ "name":"",
"age":"",
"height": "",
"sex":""
},{
"name":"",
"age":"",
"height": "",
"sex":""
}]
} } " ;
业务需求:
brand 、seeTV、age字段需要查询码表并且转码
分析:
首先对字段进行分层解析,字段重复,以层级来区分,如:
msgBody.age
msgBody.girlsFriends.age
msgBody.friends.age
已层级来确定具体转码的字段,这样就需要,配置一张,与码表的关联的层级关系表,如:
码表字段: A码值 A码值名称 B码值 B码值名称 码值类型
关系表字段:需要转码的字段 字段在码表中的类型 字段的层级 (另:根据实际需求来定限制,可加接口名字,字段状态 等)
实现:
基于FastJson2 写的工具类:
public class FastJson2Utils {
/**
* 递归查询
*/
public static JSONObject putString(JSONObject jsonObject , String keys , String type , List<CodeDto> list){
//在使用split的方法进行分隔时,要对这几种特殊字符进行"\\"分隔 | * ^ : .
String[] split = keys.split("\\.");
if (split.length>1){
for (String key : split){
String targetKey = keys.substring(keys.indexOf(".") + 1);
//pand
if (jsonObject.get(key) instanceof JSONObject){
JSONObject innerObj = (JSONObject) jsonObject.get(key);
if (type.equals(targetKey)){
String values = innerObj.getString(type);
for (CodeDto dto:list){
if (dto.getCodetp().equals(values)){
innerObj.put(type,dto.getCodeTh());
}
}
}
putString(innerObj,targetKey,type,list);
}
if (jsonObject.get(key) instanceof JSONArray){
JSONArray jsonArray = (JSONArray) jsonObject.get(key);
}
}
}
if (!list.get(0).getType().contains(".")){
if (type.equals(keys)){
String value = jsonObject.getString(type);
for (CodeDto dto:list){
if (dto.getCodetp().equals(value)){
jsonObject.put(type,dto.getCodeTh());
}
}
}
}
return jsonObject;
}
public static JSONArray putString(JSONArray jsonArray , String keys , String type , List<CodeDto> list){
if (jsonArray != null){
Iterator<?> il = jsonArray.iterator();
while (il.hasNext()){
Object key = il.next();
if (key instanceof JSONObject){
JSONObject innerObj = (JSONObject) key;
if (type.equals(keys)){
String value = innerObj.getString(type);
for (CodeDto dto :list){
if (dto.getCodetp().equals(value)){
innerObj.put(type,dto.getCodeTh());
}
}
}
putString(innerObj,keys,type,list);
}else if (key instanceof JSONArray){
JSONArray innerObj = (JSONArray) key;
putString(innerObj,keys,type,list);
}
}
}
return jsonArray;
}
public static void getString(JSONObject jsonObject,String keys,String type ,List<String> list){
String[] split = keys.split("\\.");
if (split.length>1){
for (String key : split){
String targetKey = keys.substring(keys.indexOf(".") + 1);
if (jsonObject.get(key) instanceof JSONObject){
JSONObject innerObj = (JSONObject) jsonObject.get(key);
String value = innerObj.getString(targetKey);
if (StringUtils.hasText(value)){
list.add(value);
}
getString(innerObj,targetKey,type,list);
}
if (jsonObject.get(key) instanceof JSONArray){
JSONArray jsonArray = (JSONArray) jsonObject.get(key);
getString(jsonArray,targetKey,type,list);
}
}
}
if (!type.contains(".")){
String value = jsonObject.getString(keys);
if (StringUtils.hasText(value)){
list.add(value);
}
}
}
public static void getString(JSONArray jsonArray,String keys ,String type,List<String> list){
if (jsonArray != null){
Iterator<Object> il = jsonArray.iterator();
while (il.hasNext()){
Object key = il.next();
if (key instanceof JSONObject){
JSONObject innerObj = (JSONObject) key;
String value = innerObj.getString(keys);
if (StringUtils.hasText(value)){
list.add(value);
}
getString(innerObj,keys,type,list);
}else if (key instanceof JSONArray){
JSONArray innerObj = (JSONArray) key;
getString(innerObj,keys,type,list);
}
}
}
}
}
调用:
public class Test {
@Autowired
TestService service;
public String test(){
String str = "接收的字符串";
JSONObject obj = JSONObject.parseObject(str);
List<CodeDto> list = service.selectCodes("填自己的业务条件");
Map<String, List<CodeDto>> collect = list.stream().collect(Collectors.groupingBy(CodeDto::getType));
for (String keys :collect.keySet()){
ArrayList<String> slist = new ArrayList<>();
FastJson2Utils.getString(obj,keys,keys,slist);
List<String> clist = list.stream().filter(item -> item.getType().equals(keys)).map(CodeDto::getCodetp).distinct().collect(Collectors.toList());
//求差集
List<String> res = slist.stream().filter(s -> !clist.contains(s)).collect(Collectors.toList());
if (!ObjectUtils.isEmpty(res)){
throw new CodecException("码表值不存在"+keys+" "+res);
}else {
String type = keys.substring(keys.lastIndexOf(".") + 1);
//转码后的的obj
JSONObject objs = FastJson2Utils.putString(obj, keys, type, collect.get(keys));
}
}
return null;
}
}
sql:
select c.code_tp , c.code_th ,r.keys type from '码表' c left join '关系表' r on c.type = r.type where r.interface = ? and r.status ='0' ;