import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zz.framework.constant.AppConstant;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.Set;
/**
* json工具
*
* @author Gao Zhengxing
* @date 2022-04-29 18:18
*/
@Slf4j
public class JsonUtil {
private JsonUtil() {
}
/**
* 对象转Map (fastjson 方式)
*
* @param bean 需要转换的bean
* @return
*/
public static Map fastJsonBean2Map(Object bean) {
return JSON.parseObject(JSON.toJSONString(bean),
new TypeReference<>() {
});
}
/**
* 对象转Map (fastjson 方式) 转换为x_x 蛇形格式
*
* @param bean 需要转换的bean
* @return
*/
public static Map javaBean2SnakeMap(Object bean) {
return JSON.parseObject(JSON.toJSONString(bean, Singleton.INSTANCE.getSnakeCaseSerializeConfig()),
new TypeReference<>() {
});
}
/**
* 比较2个json数据格式是否一致
*
* @param sourceJsonObj json模板
* @param responseJsonObj 调用接口组合的json返回值
* @return
*/
public static boolean compareFormat(JSONObject sourceJsonObj, JSONObject responseJsonObj) {
StringBuilder errorMessage = new StringBuilder();
containsJsonObject(sourceJsonObj, responseJsonObj, errorMessage);
if (errorMessage.length() > 0) {
log.error("JsonUtil#compareFormat 比较json错误信息:" + errorMessage);
return false;
}
return true;
}
/**
* @param sourceJsonObj 来源数据
* @param responseJsonObj 与返回数据k
* @param errorMessage 错误信息
*/
public static void containsJsonObject(JSONObject sourceJsonObj, JSONObject responseJsonObj, StringBuilder errorMessage) {
Set responseSet = responseJsonObj.keySet();
Set sourceSet0 = sourceJsonObj.keySet();
//报告模板包含返回报告
if (!sourceSet0.isEmpty() && !responseSet.isEmpty() && sourceSet0.equals(responseSet)) {
for (String key : responseSet) {
Object responseObj = responseJsonObj.get(key);
Object sourceObj = sourceJsonObj.get(key);
//来源和返回都是最终value
if (judgeSourceAndResponseIsValue(sourceObj, responseObj)) {
boolean responseObjIsEmpty = responseObj == null || responseObj.toString().length() == 0;
//如果与返回数据k为空, 使用默认值
if (responseObjIsEmpty && sourceObj != null) {
responseJsonObj.put(key, sourceObj);
}
} else {
sourceContainsResponse(key, null, errorMessage, sourceObj, responseObj);
}
}
} else {
errorMessage.append("模板数据key:" + sourceSet0 + "与返回数据key:" + responseSet + "不匹配. ");
}
}
/**
* 来源和返回都是最终value
*
* @param sourceObj
* @param responseObj
* @return
*/
static boolean judgeSourceAndResponseIsValue(Object sourceObj, Object responseObj) {
//responseObj 为最终value 不能继续递归为JSONObject或JSONArray
boolean judgeResponseObj = responseObj instanceof JSONObject || responseObj instanceof JSONArray;
boolean judgeSourceObj = sourceObj instanceof JSONObject || sourceObj instanceof JSONArray;
return !judgeResponseObj && !judgeSourceObj;
}
/**
* 递归判断
*
* @param key JSONObject 的参数
* @param size JSONArray 的参数
* @param errorMessage
* @param sourceObj
* @param responseObj
*/
static void sourceContainsResponse(String key, Integer size, StringBuilder errorMessage, Object sourceObj, Object responseObj) {
if (responseObj instanceof JSONObject && sourceObj instanceof JSONObject) {
//保留value为null的key
String responseStr = JSON.toJSONString(responseObj, SerializerFeature.WriteMapNullValue);
JSONObject responseJson = JSON.parseObject(responseStr);
JSONObject sourceJson = JSON.parseObject(sourceObj.toString());
containsJsonObject(sourceJson, responseJson, errorMessage);
} else if (responseObj instanceof JSONArray && sourceObj instanceof JSONArray) {
//保留value为null的key
String responseStr = JSON.toJSONString(responseObj, SerializerFeature.WriteMapNullValue);
JSONArray responseJson = JSON.parseArray(responseStr);
JSONArray sourceJson = JSON.parseArray(sourceObj.toString());
containsJsonArray(sourceJson, responseJson, errorMessage);
} else {
if (key == null) {
errorMessage.append("第" + size + "个" + sourceObj + "层数据格式不匹配" + responseObj + ". ");
} else {
errorMessage.append(key + "层数据格式不匹配" + ". ");
}
}
}
/**
* @param sourceJsonObj 来源数据
* @param responseJsonObj 与返回数据k
* @param errorMessage 错误信息
*/
public static void containsJsonArray(JSONArray sourceJsonObj, JSONArray responseJsonObj, StringBuilder errorMessage) {
//报告模板包含返回报告
if (!sourceJsonObj.isEmpty() && !responseJsonObj.isEmpty() && sourceJsonObj.size() == responseJsonObj.size()) {
for (int i = 0; i < responseJsonObj.size(); i++) {
Object responseObj = responseJsonObj.get(i);
Object sourceObj = sourceJsonObj.get(i);
//来源和返回为JSON格式
if (!judgeSourceAndResponseIsValue(sourceObj, responseObj)) {
sourceContainsResponse(null, i, errorMessage, sourceObj, responseObj);
}
}
} else {
errorMessage.append("模板数据:" + sourceJsonObj + "与返回数据:" + responseJsonObj + "不匹配. ");
}
}
}