package utils;
import com.google.gson.*;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
/**
* 使用 gson 封裝的操作 json 的工具類
*/
public class EasyJson {
/**
* 全局的 Gson 轉換對象
*/
private static final Gson gson = new Gson();
/**
* 通過父級對象實現鏈式結構
*/
private EasyJson parent;
/**
* 保存數據的對象
*/
private JsonElement data;
/**
* 根據數據創建一個EasyJson的對象,該對象位於parent對象的下一層
* @param parent 新建EasyJson對象的上層對象
* @param isObj 區分是 JsonArray 對象,還是 JsonObject 對象
*/
private EasyJson(EasyJson parent, boolean isObj) {
this.parent = parent;
this.data = isObj ? new JsonObject() : new JsonArray();
}
/**
* 靜態的工具類構造方法
* @return 獲取EasyJson的頂層實例
*/
public static EasyJson builder() {
return new EasyJson(null, Boolean.TRUE);
}
/**
* 創建下一層EasyJson對象,並將新建的對象返回
* @param name 新建的EasyJson對象在上級對象中的名稱
* @return 返回新建的 JsonObject 對象
*/
public EasyJson subObj(String name) {
EasyJson sub = new EasyJson(this, Boolean.TRUE);
this.put(name, sub.data);
return sub;
}
/**
* 基於當前 JsonArray 對象,創建下一層EasyJson對象
* @return 返回新建的 JsonObject 對象
*/
public EasyJson subObj() {
EasyJson sub = new EasyJson(this, Boolean.TRUE);
this.put(sub.data);
return sub;
}
/**
* 創建下一層EasyJson對象,並將新建的對象返回
* @param name 新建的EasyJson對象在上級對象中的名稱
* @return 返回新建的 JsonArray 對象
*/
public EasyJson subArr(String name) {
EasyJson sub = new EasyJson(this, Boolean.FALSE);
this.put(name, sub.data);
return sub;
}
/**
* 基於當前 JsonArray 對象,創建下一層EasyJson對象
* @return 返回新建的 JsonArray 對象
*/
public EasyJson subArr() {
EasyJson sub = new EasyJson(this, Boolean.FALSE);
this.put(sub.data);
return sub;
}
/**
* 結束子 EasyJson 對象的操作,返回上層對象
* @return 返回上層對象
*/
public EasyJson endSub() {
return this.parent;
}
/**
* 給 JsonObject 對象添加鍵值對
* @param name 鍵
* @param val 值
* @return 返回當前 EasyJson 對象
*/
public EasyJson put(String name, Object val) {
if (data instanceof JsonObject) {
((JsonObject) data).add(name, adapter(val));
}
return this;
}
/**
* 給 JsonArray 對象添加值
* @param val 值
* @return 返回當前 EasyJson 對象
*/
public EasyJson put(Object val) {
if (data instanceof JsonArray) {
((JsonArray) data).add(adapter(val));
}
return this;
}
/**
* 將 Object 類型的數據構造爲適配的 JsonElement 對象
* 當前支持的類型有:基本類型、string、Collection、Map
* @param obj 數據
* @return 返回適配的 JsonElement 對象
* @exception IllegalArgumentException 如果參數是不支持類型,將會拋出該異常
*/
private JsonElement adapter(Object obj) {
if (obj == null) {
return JsonNull.INSTANCE;
} else if (obj instanceof JsonElement) {
return (JsonElement) obj;
} else if (obj instanceof String) {
return new JsonPrimitive((String) obj);
} else if (obj instanceof Number) {
return new JsonPrimitive((Number) obj);
} else if (obj instanceof Character) {
return new JsonPrimitive((Character) obj);
} else if (obj instanceof Boolean) {
return new JsonPrimitive((Boolean) obj);
} else if (obj instanceof Collection) {
Collection c = (Collection) obj;
return adapterJsonArray(c);
} else if (obj.getClass().isArray()) {
return adapterJsonArray(obj);
} else if (obj instanceof Map) {
Map map = (Map) obj;
return adapterJsonObject(map);
} else {
throw new IllegalArgumentException("Cannot adapter this classType:" + obj.getClass().getName());
}
}
/**
* 將集合類型的數據適配爲 JsonArray 對象
* @param c 數據
* @return 返回適配的 JsonArray 對象
*/
private JsonArray adapterJsonArray(Collection c) {
JsonArray arr = new JsonArray();
for (Object o : c) {
arr.add(adapter(o));
}
return arr;
}
/**
* 將數組類型的數據適配爲 JsonArray 對象
* @param arr 數據
* @return 返回適配的 JsonArray 對象
* @exception IllegalArgumentException 如果參數不是數組類型,將會拋出該異常
*/
private JsonArray adapterJsonArray(Object arr) {
JsonArray jsonArr = new JsonArray();
int length = Array.getLength(arr);
for (int i = 0; i < length; i++) {
JsonElement ele = adapter(Array.get(arr, i));
jsonArr.add(ele);
}
return jsonArr;
}
/**
* 將 Map 類型的數據適配爲 JsonObject 對象
* @param map 數據
* @return 返回適配的 JsonObject 對象
* @exception IllegalArgumentException 如果 map 中含有值爲 null 的鍵,將會拋出該異常
*/
private JsonObject adapterJsonObject(Map map) {
JsonObject jsonObj = new JsonObject();
for (Object o : map.keySet()) {
if (o == null) {
throw new IllegalArgumentException("Map key cannot is empty.");
}
String key = o.toString();
JsonElement val = adapter(map.get(key));
jsonObj.add(key, val);
}
return jsonObj;
}
public String string() {
return gson.toJson(this.data);
}
}
測試代碼:
@Test
public void testEasyJson() {
String json = EasyJson.builder()
.subObj("query")
.subObj("bool")
.subArr("must_not")
.subObj().subObj("match").subObj("creative_file").put("query", "").endSub().endSub().endSub()
.subObj().subObj("match").subObj("creative_checksum").put("query", "").endSub().endSub().endSub()
.endSub()
.subArr("must")
.subObj().subObj("match").subObj("pf").put("query", "iOS").endSub().endSub().endSub()
.subObj().subObj("match").subObj("adt").put("query", "f").endSub().endSub().endSub()
.subObj().subObj("range").subObj("dt").put("from", "20181201").put("to", "20190326").endSub().endSub().endSub()
.subObj().subObj("terms").subArr("country_iso").put("CN").put("US").endSub().endSub().endSub()
.subObj().subObj("wildcard").put("category", "*").endSub().endSub()
.endSub()
.endSub()
.endSub()
.string();
System.out.println(json);
}
感謝參考博文:https://blog.csdn.net/axuanqq/article/details/51441590
最後小小的感嘆一下,強大的elasticsearch的恐怖的查詢json…
end~