项目背景:
需要对一个JSONArray对象数组进行解析,并把数据解析填充进实体中。由于字段太多,不愿通过if else的方式判断来赋值。遂想到通过反射的方式来实现功能
入参demo如下:
"data": [
{
"column": "age",
"result": "20",
},
{
"column": "height",
"result": "181",
},
{
"column": "weight",
"result": "140",
}
//还有很多其他的字段,类型均相同
]
相应的实体类demo
public class Student {
private Integer age;
private Integer height;
private Integer weight;
}
解决方案:
1、先将jsonarray数据通过遍历解析到map中
2、通过反射获取字段数组,遍历获取字段名,通过map获取相应结果
注意:
需要实体类中字段属性和jsonarray中做到相同
代码如下:
public Student handleObject(JSONArray jsonArray) {
Map<String, Object> map = jsonArray2Map(jsonArray);
Student student = convent(Student.class, map);
return student;
}
/**
* json数组转换成相应map
*
* @param jsonArray
* @return
*/
private Map<String, Object> jsonArray2Map(JSONArray jsonArray) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
String key = item.getString("column");
map.put(key, Integer.valueOf(item.getString("result")));
}
return map;
}
/**
* 给实体赋值,由于不止一个需要这样,所以做成泛型的方式
* @param clazz
* @param map
* @param <T>
* @return
*/
private <T> T convent(Class<T> clazz, Map<String, Object> map) {
T t = null;
try {
t = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
//跳过访问控制
field.setAccessible(true);
try {
if (map.containsKey(field.getName())) {
field.set(t, map.get(field.getName()));
}
} catch (IllegalAccessException e) {
System.out.println("属性注入失败:" + e);
}
}
return t;
}
后记
该方法只适合对类型一致的数据,数据类型的不一致时,还在考虑中。后续再更新