abstract
The docking students provide a jar, and the bean s in it are 4-level nested, and there is no document. Looking at so many attributes, I feel a little confused. Accustomed to the document format of swaggger, I wonder if there is a way to realize this requirement. Did you find it online, and then did it yourself.
keyword
Reflect one key initialization bean, serialization and retain multi-level null
1. Problem background
The docking students provide a jar, and the bean s in it are 4-level nested without a document. Looking at so many attributes, I feel a little confused. Accustomed to the document format of swaggger, I wonder if there is a way to realize this requirement
2. Problem essence
- The structure of a bean is displayed in json
3. Difficulties
- The structure of a bean is multi-level
- The bean contains custom classes
- The bean contains static classes and internal classes
4. Possible implementations
4.1. Use three-party serialization tools, such as Gson
XXXTaskAddInput xxxTaskAddInput=new XXXTaskAddInput(); Gson gson=new GsonBuilder().serializeNulls().create(); System.out.println(gson.toJson(xxxTaskAddInput));
result
{ "groupId": null, "groupName": null, "tasks": null }
It is obvious from the results that only one level of null attribute is retained. Therefore, Gson's serializeNulls function does not meet my needs.
4.2. Focus on initialization
It is not difficult to see that the essence of the problem is not serialization, but bean initialization. Because the first level properties are null. Secondary attributes cannot be serialized naturally. Therefore, our core is to implement variable beans and assign default values of corresponding types to all levels of properties.
Simply check Baidu, there is no directly available, and then do it yourself. Reflection is the key to solve this problem.
5. Reusable tool classes
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(); // This determines whether type is a parameterized type. For example, collection < string > is a parameterized type. if (type instanceof ParameterizedType) { // Gets the type parameter type of the type. You can check the explanation of ParameterizedType in the jdk help document. 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); } } } } }
How to use
XXXTaskAddInput xxxTaskAddInput=new XXXTaskAddInput(); setFeidValueNotNull(xxxTaskAddInput); System.out.println(new Gson().toJson(xxxTaskAddInput));
effect
{ "groupId": "", "groupName": "", "tasks": [ { "bizId": "", "bizInfo": { "receiver": "", "extendInfo": "", "organizationId": "", "exportInfos": [ { "columnIndex": 0, "rowspan": 1, "columnName": "", "columnValue": "" } ], "result": "" }, "name": "", "type": 0, "total": 0, "accountOid": "", "accountGid": "", "receiver": "" } ] }
Is it not as complex as you think? To add, swagger is implemented with the help of annotations.
6. Summary
Find problems, solve problems and summarize problems. Step by step. Looking back, the so-called difficulties are not so difficult.