基于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文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java编程将汉字转Unicode码代码示例

    上一次接触到编码的知识,还是上大学的时候,那时候学的是通信工程专业,有关编码的内容,不记得是在通信原理还是信息论与编码里面学到的了.却依然记得那个信息论与编码的老师,最喜欢吃的是尖椒肥肠盖饭,不知道是尖椒肥肠吃多了还是太聪明的缘故,三十多岁就开始拜顶了.那四年真是一段难忘的回忆... 话不多说,咱们进入正题.这里是一个简单的Java编程将汉字转Unicode码代码示例,下面是代码: package me.socketthread; public class ToUnicode { /** * @

  • Java编程Iterator迭代器设计原理及实现代码示例

    我们知道迭代器(Iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素.那么Iterator迭代器的设计原理是什么呢?迭代器问什么定义了一个借口,而不是一个类呢? 我们假设迭代器迭代数据的功能定义为了一个类,那么,会有这样的问题.不同的集合,由于数据结构不一样,所以他们的存储方式也是不一样的.也就是说,迭代器获取的时候,获取的方式是变化的,也就是不固定的.所以把这种方式定义为具体的实现是不合理的. 无论何种集合,他们肯定都有获取的功能,而且不知道什么时候就没有数据了.所有他

  • Java编程子类能否重写父类的静态方法探索

    今天突然讨论到了子类继承父类的静态方法问题,有人坚持说能写,有人说不能重写,那到底能不能冲写呢?这个问题很简单,测试一下就完了. 先是父类代码: public class Fu { public static void show() { System.out.println("父类的静态方法"); } public void method() { System.out.println("父类的一般方法"); } } 下面是子类代码: public class Zi

  • Java实现的3des加密解密工具类示例

    本文实例讲述了Java实现的3des加密解密工具类.分享给大家供大家参考,具体如下: package com.gcloud.common; import org.apache.poi.poifs.property.Child; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax

  • java中初始化MediaRecorder的实现方法

    java中初始化MediaRecorder 实现代码: private boolean initializeVideo() { Log.v(TAG, "initializeVideo"); if (mSurfaceHolder == null) { Log.v(TAG, "SurfaceHolder is null"); return false; } mMediaRecorderRecording = true; if (mMediaRecorder == nul

  • 基于JavaBean编辑器读取peroperties文件的实例

    引言 最近在重读<精通Spring+4.x++企业应用开发实战>这本书,看到了有关JavaBean编辑器的部分,了解到PropertyEditor和BeanInfo的使用.不得不说,BeanInfo是一个很强大的东西,Java中的内省也与之有一点点小关联. JavaBean.PropertyEditor与BeanInfo JavaBean简单介绍 JavaBean是一种Java写成的可重用组件,本质上还是一个Java类,但是与一般的Java类不同,JavaBean必须有一个无参的构造函数,其字

  • 通过Pandas读取大文件的实例

    当数据文件过大时,由于计算机内存有限,需要对大文件进行分块读取: import pandas as pd f = open('E:/学习相关/Python/数据样例/用户侧数据/test数据.csv') reader = pd.read_csv(f, sep=',', iterator=True) loop = True chunkSize = 100000 chunks = [] while loop: try: chunk = reader.get_chunk(chunkSize) chun

  • 基于python判断目录或者文件代码实例

    这篇文章主要介绍了基于python判断目录或者文件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1. 判断目录是否存在 'isdir',删除目录时只有该目录为空才可以 'rmdir' import os if(os.path.isdir('D:/Python_workspace/spyder_space/test_各种功能/哈哈哈哈')): #判断目录是否存在 print('yes') os.rmdir('D:/Python_work

  • 简单了解Python读取大文件代码实例

    这篇文章主要介绍了简单了解Python读取大文件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 通常对于大文件读取及处理,不可能直接加载到内存中,因此进行分批次小量读取及处理 I.第一种读取方式 一行一行的读取,速度较慢 def read_line(path): with open(path, 'r', encoding='utf-8') as fout: line = fout.readline() while line: line

  • Python模块_PyLibTiff读取tif文件的实例

    Usage example (libtiff wrapper) from libtiff import TIFF # to open a tiff file for reading: tif = TIFF.open('filename.tif', mode='r') # to read an image in the currect TIFF directory and return it as numpy array: image = tif.read_image() # to read al

  • 用PHP读取超大文件的实例代码

    去年年底的各种网站帐号信息的数据库泄漏,很是给力啊,趁机也下载了几个数据库,准备学学数据分析家来分析一下这些帐号信息.虽然这些数据信息都已经被"整理"过的,不过自己拿来学习也挺有用的,毕竟有这么大的数据量. 数据量大带来的问题就是单个文件很大,能够打开这个文件相当不容易,记事本就不要指望了,果断死机.用MSSQL的客户端也打不开这么大的SQL文件,直接报内存不足,原因据说是MSSQL在读取数据的时候,是一次性地将读取到的数据放在内存中,如果数据量过大,而内存不足,则会直接导致系统瘫掉.

  • python读取npy文件数据实例

    目录 1. 读取与保存 2. 实战案例 附:python中 .npy文件的读写操作实例 总结 Numpy binary files (NPY, NPZ) 注:.npy文件是numpy专用的二进制文件. 1. 读取与保存 import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) np.save('weight.npy', arr) loadData = np.load('weight.npy') print("----type----&qu

  • C 读取ini文件的实例详解

    C 读取ini文件 前言: 在Windows下可以用GetPrivateProfileString或GetPrivateProfileInt方便读取.ini配置文件内容,但是在Linux平台上就一筹莫展了.为了解决该问题,打算用C来读取.ini,即可不受平台的限制了. #define CONF_FILE_PATH "Config.ini" #include <string.h> #ifdef WIN32 #include <Windows.h> #include

  • 基于Python正确读取资源文件

    我们知道,当你把一个资源文件和一个.py文件放在一起的时候,你可以直接在这个.py文件中,使用文件名读取它.例如: with open('test.txt') as f: content = f.read() print('文件中的内容为:', content) 运行效果如下图所示: 但请注意,这里我是直接运行的read.py这个文件.如果资源文件是存放在一个包(package)里面,然后我们在外面调用这个包里面的.py文件会怎么样呢?我们试一试: 可以看到,现在Python 已经找不到这个文件

  • Java读取网络文件的实例代码

    目录 Java读取网络文件 输入url地址读取txt文件 Java读取网络文件问题 protocol = http host = null 通过ip地址读取文件 Java读取网络文件 输入url地址读取txt文件 /** * Created by qqg on 2018/1/3. */ import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import ja

随机推荐