第一版
再对接多个第三方的时候,返回的json及json格式、json结构可能不一致
有的可能是这样的:
{
"payload": {
"data": [{
"name1":"nA",
"value1":"bB",
"dtype": {
"code": "78978977898",
"name": "4645645656445"
},
}],
"status": "SUCCESS"
},
"header": {
"pv": "1.0",
"oid": "123"
}
}
也有的可能是这样的:
{
"1": {
"type": "abc",
"name": "abca",
"value": {
"dd": "dd",
"cc": "cc",
"ee": "ee",
"ff": {
"fa": "faa",
"fb": fbb
}
},
}
}
还有可能是这样的:
{
"requestId": "798456130",
"code": 200,
"message": "成功",
"data": [
{
"aa": "aa",
"qw": "qw",
"qwe": "qwe",
"er": "er",
"wt": "wt1",
"wt2": "wt2"
}
]
}
可能各不相同,废话不多说了
第一步:定义规则:
第一个例子规则为:
{
"type": "Object",
"property": [{
"name": "payload.data",
"type": "List",
"mapName": "data",
"mapValue": "value",
"property": [{
"name": "name1",
"type": "String",
"mapValue": "value",
"mapName": "name"
}, {
"name": "value1",
"type": "String",
"mapValue": "value",
"mapName": "value"
}, {
"name": "dtype.code",
"type": "String",
"mapValue": "value",
"mapName": "type"
}, {
"name": "dtype.name",
"type": "String",
"mapValue": "value",
"mapName": "dtypename"
}]
}]
}
第二步骤:定义规则类
@NoArgsConstructor
@Data
public class InterMap {
@JSONField(name = "type")
private String type;
@JSONField(name = "property")
private List<PropertyBean> property;
@NoArgsConstructor
@Data
public static class PropertyBean {
@JSONField(name = "name")
private String name;
@JSONField(name = "type")
private String type;
@JSONField(name = "mapName")
private String mapName;
@JSONField(name = "mapValue")
private String mapValue;
@JSONField(name = "property")
private List<PropertyBean> property;
}
}
第三步:写方法 (此方法可以继续优化,如可写成递归函数、用反射等等,这里暂不优化,后续再加进来)
public static String parseMapDbList(String dbJson, String originJson){
Map<String, Object> resultMap = Maps.newHashMap();
try {
InterMap interMap = JSONObject.parseObject(dbJson, InterMap.class);
cn.hutool.json.JSONObject originJsonObject = JSONUtil.parseObj(originJson);
List<InterMap.PropertyBean> propertyBeanList = interMap.getProperty();
propertyBeanList.stream().forEach(propertyBean -> {
String name = propertyBean.getName();
String type = propertyBean.getType();
List data = Lists.newArrayList();
String mapName = propertyBean.getMapName();
List<InterMap.PropertyBean> sunPropertyList = propertyBean.getProperty();
if (type.equals("List")){
List originList = originJsonObject.getByPath(name, List.class);
originList.stream().forEach(o -> {
Map<String, Object> map = Maps.newHashMap();
sunPropertyList.stream().forEach(propertyBean1 -> {
String name1 = propertyBean1.getName();
String mapValue = propertyBean1.getMapValue();
String type1 = propertyBean1.getType();
Object byPath = null;
if (mapValue.equalsIgnoreCase("value")){
byPath = JSONUtil.getByPath(JSONUtil.parse(o), name1);
}
if (type1.equals("String")){
map.put(propertyBean1.getMapName(), byPath);
}
});
data.add(map);
});
} else if (type.equals("Map")){
Map originMap = originJsonObject;
originMap.keySet().stream().forEach(o -> {
Map<String, Object> map = Maps.newHashMap();
sunPropertyList.stream().forEach(propertyBean1 -> {
String name1 = propertyBean1.getName();
String mapValue = propertyBean1.getMapValue();
String type1 = propertyBean1.getType();
Object byPath = null;
if (mapValue.equalsIgnoreCase("value")){
byPath = JSONUtil.getByPath(JSONUtil.parse(originMap.get(o)), name1);
}
if (mapValue.equalsIgnoreCase("p-key")){
byPath = o;
}
if (type1.equals("String")){
map.put(propertyBean1.getMapName(), byPath);
}
});
data.add(map);
});
}
resultMap.put(mapName, data);
});
return JSONUtil.toJsonStr(resultMap);
} catch (Exception e){
log.error("映射第三方数据 | originJson : {}, dbJson : {}", originJson, dbJson);
log.error("映射第三方数据失败:{}", e);
}
return null;
}
用到的第三方包为:hutool
优化第一版
1.优化规则类
@NoArgsConstructor
@Data
public class DataMapRule {
@JSONField(name = "type")
private String type;
@JSONField(name = "success")
private String success;
@JSONField(name = "property")
private List<PropertyBean> property;
@NoArgsConstructor
@Data
public static class PropertyBean {
@JSONField(name = "name")
private String name;
@JSONField(name = "type")
private String type;
@JSONField(name = "mapType")
private String mapType;
@JSONField(name = "mapName")
private String mapName;
@JSONField(name = "mapValue")
private String mapValue;
@JSONField(name = "valueProp")
private Map<String, Object> valueProp;
@JSONField(name = "property")
private List<PropertyBean> property;
}
}
2.优化json类
public static String RESULT_CODE = "code";
public static String parseDbMap(String dbJson, String originJson){
try {
DataMapRule dataMapRule = JSONObject.parseObject(dbJson, DataMapRule.class);
Object parse = JSONObject.parse(originJson);
JSON originJsonObject = JSONUtil.parse(parse);
String success = dataMapRule.getSuccess();
List<DataMapRule.PropertyBean> propertyBeanList = dataMapRule.getProperty();
Map<String, Object> resultMap = recursion(propertyBeanList, originJsonObject);
if (MapUtil.isNotEmpty(resultMap) && ObjectUtil.isNotEmpty(resultMap.get(SystemConstants.RESULT_CODE)) && StrUtil.isNotBlank(success)){
if (Convert.toStr(resultMap.get(SystemConstants.RESULT_CODE)).equals(success)){
resultMap.put("code",0);
} else {
resultMap.put("code",-1);
}
}
return JSONUtil.toJsonStr(resultMap);
}catch (Exception e){
log.warn("映射第三方数据2 | originJson : {}, dbJson : {}", originJson, dbJson);
log.warn("映射第三方数据失败:{}", e);
}
return dbJson;
}
private static Map<String, Object> recursion(List<DataMapRule.PropertyBean> propertyBeanList, JSON originJsonObject){
Map<String, Object> resultMap = Maps.newHashMap();
if (CollUtil.isNotEmpty(propertyBeanList)){
propertyBeanList.stream().forEach(propertyBean -> {
String path = propertyBean.getName();
String type = propertyBean.getType();
String mapType = propertyBean.getMapType();
String mapName = propertyBean.getMapName();
String mapValue = propertyBean.getMapValue();
Map<String,Object> valueProp = propertyBean.getValueProp();
List<DataMapRule.PropertyBean> sunPropertyList = propertyBean.getProperty();
if (BASE_LIST.equals(type)){
toList(resultMap, originJsonObject, path, mapName,mapType, sunPropertyList);
} else if (BASE_MAP.equals(type)){
toMap(resultMap, originJsonObject, path, mapName,mapType, sunPropertyList);
} else if(BASE_OBJECT.equals(type)){
toObject(resultMap, originJsonObject, path, mapName,mapType, sunPropertyList);
} else if(BASE_KEY_VAL.equals(type)){
toListMap(resultMap, originJsonObject, mapValue, mapName);
} else {
toBasic(resultMap, originJsonObject, path, mapName,mapType, valueProp);
}
});
return resultMap;
}
return resultMap;
}
/** 递归
* 适合:dbjson= {}
* 源json={
* list:[
* {key:val}
* ]
* }
* @param resultMap
* @param originJsonObject
* @param path
* @param mapName
* @param mapType
* @param sunPropertyList
*/
private static void toList(Map<String, Object> resultMap,JSON originJsonObject,
String path, String mapName,String mapType, List<DataMapRule.PropertyBean> sunPropertyList){
if (StrUtil.isBlank(mapType)){
List data = Lists.newArrayList();
List originList = originJsonObject.getByPath(path, List.class);
originList.stream().forEach(o -> {
if (o instanceof String || ObjectUtil.isBasicType(o)){
data.add(o);
return;
}
Map<String, Object> recursion = recursion(sunPropertyList, JSONUtil.parse(o));
data.add(recursion);
});
resultMap.put(mapName, data);
return;
}
listToMap(resultMap, originJsonObject, path, mapName, mapType, sunPropertyList);
}
public static final String MAP = "Map";
private static void listToMap(Map<String, Object> resultMap,JSON originJsonObject,
String path, String mapName,String mapType, List<DataMapRule.PropertyBean> sunPropertyList){
if (MAP.equals(mapType)){
Map<String, Object> dataMap = Maps.newHashMap();
List originList = originJsonObject.getByPath(path, List.class);
originList.stream().forEach(o -> {
Map<String, Object> recursion = recursion(sunPropertyList, JSONUtil.parse(o));
dataMap.putAll(recursion);
});
resultMap.put(mapName, dataMap);
return;
}
}
private static void toMap(Map<String, Object> resultMap,JSON originJsonObject, String path, String mapName,String mapType, List<DataMapRule.PropertyBean> sunPropertyList){
List data = Lists.newArrayList();
Map originMap = originJsonObject.toBean(Map.class);
if (CollUtil.isNotEmpty(sunPropertyList)){
boolean present = sunPropertyList.stream().filter(pb -> BASE_PARENT_KEY.equalsIgnoreCase(pb.getMapValue())).findAny().isPresent();
originMap.keySet().stream().forEach(key -> {
Map<String, Object> recursion = recursion(sunPropertyList, JSONUtil.parse(originMap.get(key)));
if (present) {
sunPropertyList.stream()
.filter(pb -> BASE_PARENT_KEY.equalsIgnoreCase(pb.getMapValue()))
.forEach(propertyBean1 -> {
String mapValue1 = propertyBean1.getMapValue();
if (BASE_PARENT_KEY.equalsIgnoreCase(mapValue1)){
recursion.put(propertyBean1.getMapName(), key);
}
});
}
data.add(recursion);
});
resultMap.put(mapName, data);
} else {
Object o = originMap.get(path);
if (StrUtil.isBlank(mapName)){
Map<String, Object> map1 = (Map<String, Object>) o;
resultMap.putAll(map1);
return;
}
resultMap.put(mapName, o);
}
}
private static void toBasic(Map<String, Object> resultMap,JSON originJsonObject,
String path, String mapName,String mapType,
Map<String,Object> valueProp){
Object byPath = originJsonObject.getByPath(path);
if (CollUtil.isNotEmpty(valueProp)) {
byPath = valueProp.get(String.valueOf(byPath));
}
resultMap.put(mapName, byPath);
}
/** 不是递归-终结
*
* example : {"cmd":"key","data":"val"} => {"key":"val"}
*
* key 和 val 均为源数据某个属性的值
* @param resultMap
* @param originJsonObject
* @param mapValue
* @param mapName
*/
private static void toListMap(Map<String, Object> resultMap,JSON originJsonObject,
String mapValue, String mapName){
Object key = originJsonObject.getByPath(mapName);
Object value = originJsonObject.getByPath(mapValue);
String strKey = String.valueOf(key);
if (StrUtil.isNotBlank(strKey)){
resultMap.put(String.valueOf(key), value);
}
}
private static void toObject(Map<String, Object> resultMap,JSON originJsonObject,
String path, String mapName, String mapType, List<DataMapRule.PropertyBean> sunPropertyList){
Object byPath = originJsonObject.getByPath(path);
if (CollUtil.isNotEmpty(sunPropertyList)){
Map<String, Object> recursion = recursion(sunPropertyList, JSONUtil.parse(byPath));
resultMap.put(mapName, recursion);
return;
}
resultMap.put(mapName, byPath);
}
dbjson案例1:
{"type":"Object","property":[{"name":"action","type":"String","mapName":"action","mapValue":"value"},{"name":"deviceId","type":"String","mapName":"deviceId","mapValue":"value"},{"name":"status","type":"Map","mapName":"property","mapValue":"value"}]}
dbjson案例2:
{"type":"Object","success":"200","property":[{"name":"code","type":"String","mapName":"code","mapValue":"value"},{"name":"message","type":"String","mapName":"msg","mapValue":"value"}]}
dbjson案例3:适用:如:张三的学号为123,李四的学号为456。originJson:{"123":{"name":"张三","age":"18"},"456":{"name":"李四","age":"20"}}
{"type":"Object","property":[{"name":"key","type":"Map","mapName":"data","property":[{"name":"key","type":"String","mapValue":"p-key","mapName":"deviceId"},{"name":"type","type":"String","mapValue":"value","mapName":"productKey"},{"name":"productname","type":"String","mapValue":"value","mapName":"deviceName"},{"name":"type","type":"String","mapValue":"value","mapName":"productType"}]}]}
后面可用java的设计模式进行优化,下次在加进来