基于JavaBean编辑器读取peroperties文件的实例
引言
最近在重读《精通spring+4.x++企业应用开发实战》这本书,看到了有关javabean编辑器的部分,了解到propertyeditor和beaninfo的使用。不得不说,beaninfo是一个很强大的东西,java中的内省也与之有一点点小关联。
javabean、propertyeditor与beaninfo
javabean简单介绍
javabean是一种java写成的可重用组件,本质上还是一个java类,但是与一般的java类不同,javabean必须有一个无参的构造函数,其字段必须私有化,并提供set、get方法供外界使用。根据书中所介绍,sun所制定的javabean规范很大程度山是为了ide准备的--它让ide能够以可视化的方式设置javabean的属性。
propertyeditor接口
propertyeditor是属性编辑器的接口,其作用是将一个string类型的值转换为javabean的属性。java为propertyeditor提供了一个默认的实现类propertyeditorsupport。
beaninfo接口
beaninfo用于描述javabean哪些属性可以编辑及对应属性编辑器。java为beaninfo也提供了一个默认实现--simplebeaninfo。
其他
更多有关javabean以及这两个接口的知识,可以购买这本书《精通spring+4.x++企业应用开发实战》,或者看我的copy
一个小例子
在《精通spring+4.x++企业应用开发实战》中使用的例子是根据《core java ii》的一个例子改变而成,但是有一个小缺点,该例子使用到了swing,演示时需要将代码打成jar包,使用ide组件扩展管理功能注册到ide中,不太方便,因此我特意尝试用javabean编辑器读取properties文件作为一个小例子。
定义一个javabean
我们先定义一个person类,用作javabean
/** * 一个简单的javabean * @author aming * */ public class person implements serializable { private static final long serialversionuid = 6366021085463785872l; /** * 姓名 */ private string name; /** * 年龄 */ private int age; /** * 性别 */ private gender gender; /** * 生日 */ private date birthday; /** * 是否结婚 */ private boolean married; public string getname() { return name; } public void setname(string name) { this.name = name; } public int getage() { return age; } public void setage(int age) { this.age = age; } public gender getgender() { return gender; } public void setgender(gender gender) { this.gender = gender; } public date getbirthday() { return birthday; } public void setbirthday(date birthday) { this.birthday = birthday; } public boolean ismarried() { return married; } public void setmarried(boolean married) { this.married = married; } public person() { super(); } @override public string tostring() { return "person [name=" + name + ", age=" + age + ", gender=" + gender + ", birthday=" + birthday + ", married=" + married + "]"; } }
其中gender是我自定义的枚举,其代码如下:
/** * 表示性别的枚举类 * @author aming * */ public enum gender { m(1,"男"),f(2,"女"); private int id; private string gendername; public string getgendername() { return gendername; } gender(int id,string gendername){ this.id = id; this.gendername = gendername; } public static gender getgender(int id) { for(gender gender:values()) { if(gender.id == id) { return gender; } } return m; } public static gender getgender(string gendername) { for(gender gender:values()) { if(gender.gendername == gendername) { return gender; } } return m; } }
实现propertyeditor
person类中有5个字段,分别使用string、int、gender、date和boolean这5中类型,其中对string类型变量name我们使用propertyeditorsupport这个默认实现就可以了,其他的类型我们需要自定义去实现propertyeditor接口--int对应integerpropertyeditor、gender对应genderpropertyeditor、date对应datepropertyeditor以及boolean对应booleanpropertyeditor。
integerpropertyeditor
integerpropertyeditor类继承了propertyeditorsupport类和实现propertyeditor接口(个人习惯实现接口的时候同时继承一个默认实现,这样我可以只关心我所需要实现的方法,当然,这个默认实现最好是一个抽象类),重写了getastext()方法和setastext(string text),其代码如下:
@override public string getastext() { return string.valueof((int)getvalue()); } @override public void setastext(string text) throws illegalargumentexception { try { setvalue(integer.parseint(text)); } catch(numberformatexception e) { throw new illegalargumentexception(e); } }
genderpropertyeditor
genderpropertyeditor主要是将外部获得到的字符串去转换为gender,其实现思路是,先尝试将该字符串转换为integer类型,如果转换成功则将转换得到integer值通过gender枚举的静态方法getgender(int id)获取gender类型的变量;如果转换失败,则将该字符串看作gendername,再去获取gender。至于gender到字符串,直接返回gendername就可以了。主要代码如下:
@override public string getastext() { gender value = (gender)getvalue(); return value.getgendername(); } @override public void setastext(string value) throws illegalargumentexception { try { setvalue(gender.getgender(integer.valueof(value))); }catch(numberformatexception ex) { setvalue(gender.getgender(value)); } }
datepropertyeditor
datepropertyeditor的思路和genderpropertyeditor相似,其核心代码献上:
private dateformat df; @override public string getastext() { date date = (date)getvalue(); return df.format(date); } @override public void setastext(string text) throws illegalargumentexception { try { setvalue(df.parse(text)); } catch (parseexception e) { throw new illegalargumentexception(e); } } public datepropertyeditor() { super(); this.df = new simpledateformat("yyyy-mm-dd"); }
booleanpropertyeditor
booleanpropertyeditor与integerpropertyeditor一样,实现非常类似:
@override public string getastext() { return string.valueof((boolean)getvalue()); } @override public void setastext(string text) throws illegalargumentexception { setvalue(boolean.valueof(text)); }
自定义beaninfo
定义personbeaninfo类,用于描述person属性和相对应的propertyeditor。代码如下:
public class personbeaninfo extends simplebeaninfo implements beaninfo { @override public propertydescriptor[] getpropertydescriptors() { list<propertydescriptor> list = new arraylist<>(); try { // 将person中name与propertyeditorsupport绑定 propertydescriptor namepropertydescriptor = new propertydescriptor("name",person.class); namepropertydescriptor.setpropertyeditorclass(propertyeditorsupport.class); // 将person中age与integerpropertyeditor绑定 propertydescriptor agepropertydescriptor = new propertydescriptor("age",person.class); agepropertydescriptor.setpropertyeditorclass(integerpropertyeditor.class); // 将person中gender与genderpropertyeditor绑定 propertydescriptor genderpropertydescriptor = new propertydescriptor("gender", person.class); genderpropertydescriptor.setpropertyeditorclass(genderpropertyeditor.class); // 将person中birthday与datepropertyeditor绑定 propertydescriptor birthdaypropertydescriptor = new propertydescriptor("birthday",person.class); birthdaypropertydescriptor.setpropertyeditorclass(datepropertyeditor.class); // 将person中married与booleanpropertyeditor绑定 propertydescriptor marriedpropertydescriptor = new propertydescriptor("married",person.class); marriedpropertydescriptor.setpropertyeditorclass(booleanpropertyeditor.class); list.add(namepropertydescriptor); list.add(agepropertydescriptor); list.add(genderpropertydescriptor); list.add(birthdaypropertydescriptor); list.add(marriedpropertydescriptor); return list.toarray(new propertydescriptor[list.size()]); } catch (introspectionexception ex) { ex.printstacktrace(); } return null; } }
创建配置文件
因为我创建的是一个普通的java项目,因此我选择在src目录下创建person.properites文件,文件内容如下:
name=arthurming age=18 gender=1 birthday=2017-10-24 married=true
测试
测试代码
@test public void test() throws ioexception, illegalaccessexception, illegalargumentexception, invocationtargetexception, instantiationexception { properties p = new properties(); inputstream is =this.getclass().getclassloader().getresourceasstream("person.properties"); p.load(is); beaninfo beaninfo = new personbeaninfo(); propertydescriptor[] propertydescriptoies = beaninfo.getpropertydescriptors(); person person = new person(); for(propertydescriptor propertydescriptor : propertydescriptoies) { string key = propertydescriptor.getname(); string value = p.getproperty(key); method method = propertydescriptor.getwritemethod(); propertyeditor pe = (propertyeditor) propertydescriptor.getpropertyeditorclass().newinstance(); if(pe.getclass() == propertyeditorsupport.class) { //① pe.setvalue(value); } else { pe.setastext(value); } method.invoke(person,pe.getvalue()); } system.out.println(person); }
说明:代码①表示当pe类型是propertyeditorsupport,而不是我所定义propertyedtior,应该使用setvalue方法而不是setastext方法。
因为在propertyeditorsupport中,其setastext()方法为:
public void setastext(string text) throws java.lang.illegalargumentexception { if (value instanceof string) { setvalue(text); return; } throw new java.lang.illegalargumentexception(text); }
如果使用setastext()方法,那么由于value不是string类型,将会抛出illegalargumentexception。不过很遗憾我搞明白value到底实际上什么类型......
测试结果
person [name=arthurming, age=18, gender=m, birthday=tue oct 24 00:00:00 cst 2017, married=true]
小结
感觉您能容忍我拙劣的文笔看到现在,也希望你在读《精通spring+4.x++企业应用开发实战》这本书时,看到有关javabean编辑器的知识,我的这个例子可以对你有所帮助。
以上这篇基于javabean编辑器读取peroperties文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。