今天在开发中碰到这样一个场景:当请求添加项目下的目录时,传过来的是一个IndexModel,这个Model里有关于这个目录字段的详细信息,包括基础报表,实时,漏斗等信息(这些字段类型都是boolean),对应于页面上生成目录的多选框。现要将这些配置存入数据库,在数据库中存的是这个项目下的目录,比如说在页面勾选了基础报表这个选择框,就会在数据库中的menu表插入一条数据记录这个配置。这样一来,就需要对传递过来的这个IndexModel类的属性值进行判断,再决定插入数据库的信息。

下面是IndexModel这个model的基本属性:

 public class IndexModel {
private Boolean basic_report; //基础报表
private Boolean realtime; //实时
private Boolean event; //事件
private Boolean retain;// 留存
private Boolean funnel; //漏斗
private Boolean explore; //探索
private Boolean grouping; //分组
private Boolean user_portrait; //用户画像
private Boolean log; //日志 //setters and getters ..
}

当某个属性为true时,则就会将这个属性配置进数据库,当这个属性为false时,则不会进行任何操作。

由此,我想到了利用Java反射,遍历这个类的属性,然后获取到这个属性的名字和值判断,再映射成数据库表的字段,插入到数据库中去。

我们先上解决方案代码:

  Field[] fields = IndexModel.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
f.setAccessible(true); // 设置这些属性是可以访问的
try {
if(f.getGenericType().toString().endsWith("Boolean") && (Boolean) f.get(indexModel) == true) { // 得到此属性的值
IndexDto indexDto = parseIndexModelToDto(indexModel, f.getName());
projectService.addIndex(indexDto);
}
} catch (IllegalAccessException e) {
logger.error("属性类型转换异常");
}
}

在代码中先是利用反射获取类的所有对象成员的字段值,在这里由于IndexModel中的属性字段值都是private的,所以,只能使用 getDeclaredFields()获取到这些字段,至于getFields()方法,只能获取到类(及其父类)中的公有成员,这两个方法返回的都是Field类型的数组。

在获取私有成员值之前,必须调用setAccessible(true),否则的话,将会抛出异常:java.lang.IllegalAccessException:  class... can not access ,显示不能获取字段值。

另外,在需要获取成员的类型时,需要调用相应的field的getType()方法,获取field的类型有如下几种方法

  Class<?> type = field.getType();        // 通过这种方式只对普通类型的Field有效,如果该Field的类型是有泛型限制的类型,如Map<String,Integer>类型,则不能准确得到该Field的泛型参数。

  Type type = field.getGenericType();  // 为了获得指定Field的泛型类型,应该使用这个方法来获取指定Field的泛型类型

如果要获取上面对应field的被泛型限制的方法,就需要将上面的type对象强制类型转换成ParameterizedType对象,ParameterizedType代表被参数化的类型,也就是增加了泛型限制的类型,ParameterizedType类提供了两个方法:

getRawType();                            返回被泛型限制的类型;

getActualTypeArguments();        返回泛型参数类型。

然后,要获取成员变量的名称直接使用field.getName(),但是属性值则是field.get(Object),这个object是该field所属的!

最后,要是想为这个成员变量设置值,则需要调用set:field[i].set(indexModel , true);

利用反射操作bean的属性和方法的更多相关文章

  1. 利用 spring bean 的属性 init-method 解决因为数据库连接没有初始化而导致首次点击页面超慢的问题

    问题的描述: 一个项目,涉及到了 两个数据源,分别使用的是 两个不同的 数据库连接池,其中一个是 poxool 连接池,问题在于,spring在启动时,只初始化其中的一个 数据库连接池中的数据库连接, ...

  2. Spring框架bean的配置(2):SpEL:引用 Bean、属性和方法。。。

    将这些架包放入在工程目录下建立的lib文件夹里,并解压 commons-logging-1.1.1 spring-aop-4.0.0.RELEASE spring-beans-4.0.0.RELEAS ...

  3. final修饰的类,其属性和方法默认是被final修饰的吗?

    在论坛上,看到一个问题,当然,各位聪明的客官想必已经知道问题是什么了,嘿嘿,没错就是文章的标题:final修饰的类,其属性和方法默认是被final修饰的吗? 老实说,刚开始看到这个问题的时候,有点懵. ...

  4. 7 -- Spring的基本用法 -- 10... 获取其他Bean的属性值;获取Field值;获取任意方法的返回值

    7.10 高级依赖关系配置 组件与组件之间的耦合,采用依赖注入管理:但基本类型的成员变量值,应直接在代码中设置. Spring支持将任意方法的返回值.类或对象的Field值.其他Bean的getter ...

  5. 使用外部属性文件配置Bean以及Bean的生命周期方法

    1.使用外部属性文件配置Bean 在配置文件里配置 Bean 时, 有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean ...

  6. java利用反射访问类的私有(private)属性及方法

    Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ...

  7. 普通Java类获取spring 容器的bean的5种方法

    方法一:在初始化时保存ApplicationContext对象方法二:通过Spring提供的工具类获取ApplicationContext对象方法三:继承自抽象类ApplicationObjectSu ...

  8. spring(四):spring中给bean的属性赋值

    spring中给bean的属性赋值 xml文件properties标签设置 <bean id="student" class="com.enjoy.study.ca ...

  9. Spring Ioc源码分析系列--容器实例化Bean的四种方法

    Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...

随机推荐

  1. C#图片水印代码整理

    这一段公司有个项目,客户要求上传的图片要带上自定义的水印.以前也经常和朋友讨论C#图片水印方面的问题,但是从来没有实际操作过.所以,借这次项目的机会也研究了一下C#图片水印的功能!本人参考的是disc ...

  2. 7. ZooKeeper的stat结构

    ZooKeeper命名空间中的每个znode都有一个与之关联的stat结构,类似于Unix/Linux文件系统中文件的stat结构. znode的stat结构中的字段显示如下,各自的含义如下: cZx ...

  3. Python闭包

    1.概述 闭包是在其词法上下文中引用自由变量的函数. >>> def foo(): ... m=3 ... n=5 ... def bar(): ... a=4 ... return ...

  4. 【转】Entity Framework 5.0系列之自动生成Code First代码

    在前面的文章中我们提到Entity Framework的“Code First”模式也同样可以基于现有数据库进行开发.今天就让我们一起看一下使用Entity Framework Power Tools ...

  5. Django之用户登录实例

    1,django目录结构(需要用到的文件用红箭头标记): 2,首先在templates模版目录下创建login.html文件 3,将bootstrap导入到static/plugins目录下   PS ...

  6. JavaScript学习笔记(七)——函数的定义与调用

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  7. 重温CSS3

    基础不牢,地动山摇!没办法,只能重温"经典"! 1.CSS3边框:border-radius; box-shadow; border-image border-radius:r1, ...

  8. Python 日志处理(三) 日志状态码分析、浏览器分析

    在企业中,从日志中提取数据进行分析,可以帮助企业更加了解用户行为,用户最感兴趣的产品或者内容,分析得到数据后,可以决定企业在今后的走向. 从这些日志数据中,比较重要的有: 1. 用户访问最多的url, ...

  9. HTML Entity 字符实体

    目录 1. HTML Entity 2. 字符与Entity Name的互相转换 3. 字符与Entity Number的互相转换 1. HTML Entity 1.1 介绍 在编写HTML页面时,需 ...

  10. Less 编译工具

    Less 编译工具 虽然你可以选择在浏览器端使用Less,直接在页面中嵌入一个 Less.js 文件,你也可以选择在服务器端使用Less,使用命令行将Less文件编译成最终的CSS文件. 然而,这两种 ...