功能需求:
客户端、服务端通过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();
}
}
}
待续。