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	需要获取的属性名,可以是当前对象中的属性名, 也可以是当前对象中的对象的属性名
	 * @return	Object  当前对象指定属性值
	 */
	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 < fs.length; 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	所需要获取的属性名
	 * @return	Object
	 */
	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语句,传入后台自行查询,至于过滤那部分,应该是没办法抽取的,需要在各自的控制层处理一下。

记录每一次的技术心得。

时间: 2024-12-24 21:42:22

java反射获取对象的属性值和对象属性中的子属性值的相关文章

Java反射获取对象VO的属性值(通过Getter方法)

有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个Excel导出的工具类,导出的批量数据是以List类型传入的,List里的对象自然每次都不同,这取决于需要导出什么信息. 为了使用方便,将对象的属性名与属性值存于Map当中,使用时就可以直接遍历Map了. 此次的思路是通过反射和Getter方法取得值,然后记录在一个Map当中. Kick start

通过java反射获取任意对象的字段名及字段值

import java.lang.reflect.Field; public class ReflectClass3 { /** * @param args */ public static void main(String[] args) { Person p = new Person(1, "ctl", true, 'c', 2.0f, 2.0, 1L, (short) 1, (byte) 1); p.setId(0); p.setName("张三"); p.s

Java反射获取class对象的三种方式,反射创建对象的两种方式

Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName 静态方法. 前提:已明确类的全路径名. 第二种,使用 .class 方法. 说明:仅适合在编译前就已经明确要操作的 Class 第三种,使用类对象的 getClass() 方法. 适合有对象示例的情况下 package com.reflection; /** * Created by Liuxd

在不允许新建对象的条件下,将list中指定条件的值去除

package com.liujianwang.learning; import java.util.LinkedList; import java.util.List; public class ListTest { public static void main(String[] args) { /* * 在不允许新建对象的条件下,将list中指定条件的值去除. * 例如:移除list中值大于6的元素. */ //测试数据 List<Integer> list = new LinkedLi

WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了

原文:WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了 如果你写了一个 MarkupExtension 在 XAML 当中使用,你会发现你在 MarkupExtension 中定时的属性是无法使用 XAML 绑定的,因为 MarkupExtension 不是一个 DependencyObject. 本文将给出解决方案,让你能够在任意的类型中写出支持 XAML 绑定的属性:而不一定要依赖对象(DependencyObj

saddle中每一个属性赋值给到WebPlate中的同名属性

//将saddle中每一个属性赋值给到WebPlate中的同名属性   foreach (PropertyInfo info in saddle.GetType().GetProperties())   {    try    {     string objString = info.Name;     object objValue = saddle.GetType().GetProperty(objString).GetValue(saddle, null);     this.GetTy

Java反射获取类和对象信息全解析

反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题. 在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了. 获取类对象 Class.forName(String clazzName)静态方法 调用类的class属性,Person.class返回的就是Person的class对象(推荐使用) 调用某个对象的getClass()方法 具体使用还是要根据实际来选择,第一种方式是比较自由的,只要知道一个类名就可以了,其不会做该类是否存在的

java反射与注解结合使用(根据传入对象输出查询sql)

我们在项目开发中有很多地方使用到了注解,关于注解的定义与创建小伙伴可以参考我的文章<java注解>.有任何问题的小伙伴们可以在评论区指出哦,欢迎各位大佬指出问题. 今天我要说的是使用注解与反射结合使用,来使我们代码根据优雅,更加高大上(咳,装逼神器啊). 注解使用@interface 来定义,辣么我们自定义的注解,该使用获取到并且指明该注解的作用呢?java提供了反射机制,通过类的类类型我们可以根据自己需要老操作该类.有管反射的知识,可以参考我的上两章博客.好了,废话不多说,我们上代码: 需求

java反射获取注解并拼接sql语句

先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE}) @Retention(Ret