摘要
對接的同學提供一個jar過來,然后里面的bean是4級嵌套,然后也沒有個文檔。看着這么多的屬性心里有點蒙。看慣了swaggger的文檔格式,心里在想,有沒有一個方式可以實現這個需求。網上找了沒有,然后自己動手了。
關鍵字
反射一鍵初始化bean、序列化保留多級null
1、問題背景
對接的同學提供一個jar過來,然后里面的bean是4級嵌套,也沒有個文檔。看着這么多的屬性心里有點蒙。看慣了swaggger的文檔格式,心里在想,有沒有一個方式可以實現這個需求
2、問題本質
- 把一個bean的結構用json的方式展示出來
3、難點
- bean的結構是多級的
- bean中包含自定義類
- bean中包含靜態類、內部類
4、可能的實現方式
4.1、利用三方序列化工具,比如Gson實現
XXXTaskAddInput xxxTaskAddInput=new XXXTaskAddInput();
Gson gson=new GsonBuilder().serializeNulls().create();
System.out.println(gson.toJson(xxxTaskAddInput));
結果
{
"groupId": null,
"groupName": null,
"tasks": null
}
從結果明顯可以看出,只是保留了一級的null屬性。所以說Gson的serializeNulls這個功能是不滿足我的這個需求的。
4.2、專注到初始化話
不難看出問題的本質不是序列化,而在於bean的初始化。因為一級屬性都是null。二級屬性自然是無法序列化出來的。所以我們的核心是實現變量bean,給所有層級的屬性賦值對應類型的默認值就好了。
簡單的查了下百度,沒有直接可用的,然后就自己動手了。反射是解決這個問題的關鍵。
5、可復用的工具類
public static void setFeidValueNotNull(Object obj) throws Exception {
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
if (field.get(obj) == null || field.get(obj).toString().equals("[]")) {
if (field.getGenericType().toString().equals("class java.lang.String")) {
field.set(obj, "");
} else if (field.getGenericType().toString().equals("class java.lang.Integer")) {
field.set(obj, 0);
} else if (field.getGenericType().toString().equals("class java.lang.Double")) {
field.set(obj, 0.0);
} else if (field.getGenericType().toString().equals("class java.lang.Long")) {
field.set(obj, 0L);
} else {
Type type = field.getGenericType();
if (List.class.isAssignableFrom(field.getType())) {
List arraylist = new ArrayList();
// 這樣判斷type 是不是參數化類型。 如Collection<String>就是一個參數化類型。
if (type instanceof ParameterizedType) {
// 獲取類型的類型參數類型。 你可以去查看jdk幫助文檔對ParameterizedType的解釋。
Class clazz =
(Class) ((ParameterizedType) type).getActualTypeArguments()[0];
Object subObject = clazz.newInstance();
setFeidValueNotNull(subObject);
arraylist.add(subObject);
}
field.set(obj, arraylist);
} else {
Class clazz = Class.forName(field.getGenericType().getTypeName());
Object subObject = clazz.newInstance();
setFeidValueNotNull(subObject);
field.set(obj, subObject);
}
}
}
}
}
如何使用
XXXTaskAddInput xxxTaskAddInput=new XXXTaskAddInput();
setFeidValueNotNull(xxxTaskAddInput);
System.out.println(new Gson().toJson(xxxTaskAddInput));
效果
{
"groupId": "",
"groupName": "",
"tasks": [
{
"bizId": "",
"bizInfo": {
"receiver": "",
"extendInfo": "",
"organizationId": "",
"exportInfos": [
{
"columnIndex": 0,
"rowspan": 1,
"columnName": "",
"columnValue": ""
}
],
"result": ""
},
"name": "",
"type": 0,
"total": 0,
"accountOid": "",
"accountGid": "",
"receiver": ""
}
]
}
是不是沒有想象中復雜,補充一句,swagger中是借助於注解實現的。
6、總結
發現問題,解決問題,總結問題。一步一個腳印的往前走。回頭看,其實所謂的困難也沒那么難。