java反射获取属性值_java反射获取对象的属性值和对象属性中的子属性值

近段时间在做web项目,前端使用的是jQuery EasyUI。

为方便需要,准备做一个前端通用的Datagird导出Excel功能,博主也考虑过思路和最终功能,1、前端选中行导出;2、当前页导出;3、当前过滤条件导出。

想偷懒在网上找找已有的代码改改,发现大部分只能满足个别需求,使用JS导出只能满足前端,使用代码才能实现3功能。

。。。。。。

好了,说了一堆废话,回归正题,本文是在做通用自定义字段导出时所需要,根据属性名去查找对象和子对象,找到对应属性值,抓取回来放到Excel中。

直接上代码,已经封装好,直接调用即可:import java.lang.reflect.Field;

/**

* 属性(对象)值反射获取工具类

* @author 周围

* @date 2016-8-14

*/

public class ParamsReflect {

public static final String FILE_FIELD = "nameB,";

/**

* 获取当前对象对应字段的属性(对象)

* 声明,需要注意在NoSuchFieldException异常捕捉中捕获自己需要的属性字段进行拦截,告诉当查询这些属性名的时候,指定是查找的哪些对象,如果不告诉它,它是不知道的

* @param obj当前对象

* @param field需要获取的属性名,可以是当前对象中的属性名, 也可以是当前对象中的对象的属性名

* @returnObject  当前对象指定属性值

*/

public static Object getFieldValue(Object obj, String field) {

Class> claz = obj.getClass();

Field f = null;

Object fieldValue = null;

try {

f = claz.getDeclaredField(field);

f.setAccessible(true);

fieldValue = f.get(obj);

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

//此处异常捕获为:找不到属性名异常。

//注意在此处我们要手工去帮它找到field应该对象到哪个对象里的值,因为我们不知道它们之间的关系,所以需要手工指定关系,找哪个对象去关联

if(FILE_FIELD.indexOf(field) != -1) fieldValue = getCustomChildObj(obj, claz, B.class, field);

else fieldValue = null;

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return fieldValue;

}

/**

* 获取自定义子属性对象,传入指定对象名,在当前对象中找到子对象,再通过field找到子属性

* @param obj父对象名称

* @param claz父对象class反射

* @param customClass自定义判断的子对象类型

* @param field属性名

* @return Object

*/

public static Object getCustomChildObj(Object obj, Class> claz, Class> customClass, String field) {

Field[] fs = claz.getDeclaredFields();

Field f = null;

for (int i = 0; i 

f = fs[i];

if(f.getType().equals(customClass)) {

return getChildObjectParam(obj, f, field);

//return claz.getDeclaredField(f.getName());

}

}

return null;

}

/**

* 通过找到的子对象,获取到当前的属性,传入所需的属性名,得到属性值

* @param o父对象

* @param f父对象下的子对象的Field对象

* @param field所需要获取的属性名

* @returnObject

*/

public static Object getChildObjectParam(Object o, Field f, String field)  {

f.setAccessible(true);

Object obj = null;

Class> childClass = null;

Field childF = null;

Object fieldValue = null;

try {

obj = f.get(o);

childClass = obj.getClass();

childF = childClass.getDeclaredField(field);

childF.setAccessible(true);

fieldValue = childF.get(obj);

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

}

return fieldValue;

}

}

模拟测试:

对象A中有属性name,子对象B,对象B中有属性id,nameB。

B b = new B();

b.setId("b");

b.setNameB("b-name");

A a = new A();

a.setName("a-name");

a.setB(b);

Object value1 = ParamsReflect.getFieldValue(a, "name"); //获取a中的属性

Object value2 = ParamsReflect.getFieldValue(a, "nameB"); //获取b中的属性

功能比较简单,并不灵活,为应付功能,先做了一个这样的版本,以后继续完善,也留几个问题。

1、目前的版本只控制到了需要自己传入对应的子对象.class,博主还未想到怎么样设定自动匹配对应的属性值。(也想过直接对该对象和里面的所有子对象进行扫描,拿需要获取值得字段进去得,但是发现一个问题,不同对象中的属性,可能存在属性名相同,所以扫描无法控制唯一性)

2、以上版本是用于EasyUI中的Datagrid,该控件中的field属性无法命名为"b.nameB",不能直接用子对象去获取子属性,博主也尝试改过EasyUI的JS源码,让其支持子对象.属性的方式,但又存在其他的问题不兼容这个方式,所以以这个方案实施,有大神有其他办法吗。

3、最终版,作者是准备在空闲的时候完善升级它,不局限于Datagrid,所有都支持的导出Excel功能。这里准备做的是,先将对象传入后台,并进入数据库查询,将对应实体的表,字段名,字段类型全部获取到。之后处理成对应格式,是子对象的,用子对象属性名.子对象属性拼接好,返回前台,让用户选择需要导出的列,选择完毕后返回后台,拼接这些字段,生成SQL语句,传入后台自行查询,至于过滤那部分,应该是没办法抽取的,需要在各自的控制层处理一下。

记录每一次的技术心得。

你可能感兴趣的:(java反射获取属性值)