功能需求:
客户端、服务端通过socket通信发送信息,本机模拟服务端,开启端口号为0000的socket,用于接收客户端发送的数据,客户端向服务端发送数据并获取服务端返回的数据。
功能实现很简单,但是现在想把关于数据库连接的一些配置信息,比如数据库地址(本机为127.0.0.1),端口号(本机为0000),超时时间,缓冲区大小等等配置写在一个配置文件中,然后读取这个配置文件,创建一个服务器连接对象,将这些信息都作为对象的成员变量,从配置文件中读取数据并自动为所有成员变量赋值。
下面的实现用到了java的反射机制。
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; /** * 定义服务器地址对象,从指定目录的配置文件中读取服务器地址/端口号/超时时间/字符缓冲区大小/超时等待时间 * * @author jwenjian * */ public class ServerAddress { /* * 注意: * 1 成员变量定义为public static 方便调用时直接用类名.成员变量访问;为其设置getter/setter方法,为了在静态代码块中为其赋值 * 2 定义成员变量时,基本数据类型要使用其包装类来声明,如:int=〉Integer,类型转换时需要调用Integer.valueOf(String arg0)的方法,而int没有这个方法 * 3 成员变量必须在配置文件中有对应的数据 */ public static String address; public static Integer port; public static Integer conntimeout; public static Integer timeout; public static Integer buffsize; public static String getAddress() { return address; } public static void setAddress(String address) { ServerAddress.address = address; } public static int getPort() { return port; } public static void setPort(Integer port) { ServerAddress.port = port; } public static int getConntimeout() { return conntimeout; } public static void setConntimeout(Integer conntimeout) { ServerAddress.conntimeout = conntimeout; } public static int getTimeout() { return timeout; } public static void setTimeout(Integer timeout) { ServerAddress.timeout = timeout; } public static int getBuffsize() { return buffsize; } public static void setBuffsize(Integer buffsize) { ServerAddress.buffsize = buffsize; } /** * 将字符串首字母大写 * @param input 待处理的字符串 * @return 首字母大写处理后的字符串 */ public static String firstLetterToUpCase(String input) { String firstLetter = input.substring(0, 1); return firstLetter.toUpperCase() + input.substring(1, input.length()); } static { Properties properties = new Properties(); try { InputStream in = new FileInputStream( ".\\config\\Client\\serverAddress.properties"); properties.load(in); //利用java反射机制来获取ServerAddress的class Class clazz = Thread .currentThread() .getContextClassLoader() .loadClass( "connectionHelper.ServerAddress"); //通过clazz创建ServerAddress的实例 ServerAddress sa = (ServerAddress) clazz.newInstance(); //获取所有的成员变量 Field[] fields = clazz.getDeclaredFields(); //为成员变量遍历赋值 for (Field field : fields) { //获取对应的成员变量的set方法:getDeclaredMethod(String arg0,Class arg1)的第二个参数,通过field.getType()动态调用成员变量对应的set方法 Method method = clazz .getDeclaredMethod("set" + firstLetterToUpCase(field.getName()),field.getType()); //判断方法的形参类型是否是String if(field.getType().equals(java.lang.String.class)){ //如果是,则直接执行该方法,实参为从属性文件中读取的该成员变量对应的值 method.invoke(sa, properties.getProperty(field.getName())); }else{ //否则,通过成员变量的实际类型对应的class利用反射机制,调用其valueOf()方法,将属性文件中的字符串强制转换成需要传入的形参类型,并执行该方法为该成员变量赋值 method.invoke(sa, field.getType().getDeclaredMethod("valueOf", java.lang.String.class).invoke(field, properties.getProperty(field.getName()))); } } in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
目前只是初步实现这个功能,接下来再完善,准备写一个Helper类,功能:自动创建与配置文件同名的java类,将配置文件中的各个属性设为这个java类中的成员变量并自动赋值。
待续。
原文:http://www.cnblogs.com/mestory/p/4875416.html