Hey BeanUtils
God helps those who help themselves.– 天助自助者.
闲暇之余,写了一个封装工具类BeanUtils,模仿了spring中的参数封装类,实现了参数的封装,具体代码如下:
BeanUtilsTest 方法fillObject() 方法参数 params 类
//模仿 springmvc中的封装工具类
public class BeanUtilsTest {
// 时间类的 默认
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
//存放转换器,key是目标类型的类型, value是转换器
private static Map<Class, Convert> convertMap = new HashMap<>();
// 可以自定义时间类型.
public static void register(Class c, Convert convert) {
convertMap.put(c, convert);
}
/**
* 封装类 实现方法
*
* @param params 参数 key 是属性名 value 是值
* @param tClass 被封装的类的类型
* @param <T>
* @return
*/
public static <T> T fillObject(Map<String, String[]> params, Class<T> tClass) {
// 创建该泛型 类的实例
T t = null;
// 根据 类的class 进行实例化 通过反射
try {
// 得到实例化对象
t = tClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// 获得请求参数 String 就是 key Stringp[] 就是对应的值
Set<Map.Entry<String, String[]>> entries = params.entrySet();
// 进行 遍历
for (Map.Entry<String, String[]> entry : entries) {
// 得到属性
String key = entry.getKey();
// 得到值
String[] value = entry.getValue();
// 根据类 和属性 进行得到其set方法
try {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(key, tClass);
// 得到 set 方法
Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null) {
// 对 set方法进行赋值 注意 参数是 String[] 类型的 判断 属性值是什么类型的,如果是单体类型的,那么可以只要数组的第一个值
Class<?>[] parameterTypes = writeMethod.getParameterTypes();
// 理论上 set 方法 只有一个参数 只要第一个参数类型 然后进行判断
Class<?> parameterType = parameterTypes[0];
if (parameterType == String.class) {
// 把数组变成 字符串类型的 赋值给 set方法
writeMethod.invoke(t, Arrays.toString(value));
// 如果是 数组类型的 那么 进行 赋值
} else if (parameterType == String[].class) {
// 把 数组类型的 转换成 object[] 数组类型 进行赋值
writeMethod.invoke(t, new Object[]{value});
// 如果 是基本类型的 话 那么值 只有一个,,所以 只取数组的第一个
} else if (parameterType == int.class || parameterType == Integer.class) {
// 判断 数组长度,,如果长度不是1 那么说明有错误
if (value.length != 1) {
throw new RuntimeException("属性" + key + "的数组长度错误");
} else {
writeMethod.invoke(t, Integer.parseInt(value[0]));
}
// 如果是 时间类型的
} else if (parameterType == Date.class) {
// 使用 自定义类型的 时间,还是 规定的
Date date = null;
// 看看有没有用户定义的 时间类型
Convert convert = convertMap.get(Date.class);
if (convert != null) {
//通过自定义转换器实现 结果是 自定义类型的
date = (Date) convert.convert(value[0]);
// 就是默认的
} else {
try {
date = simpleDateFormat.parse(value[0]);
} catch (Exception e) {
try {
date = simpleDateFormat1.parse(value[0]);
} catch (Exception e1) {
e.printStackTrace();
}
e.printStackTrace();
}
}
// 把时间装进去
writeMethod.invoke(t, date);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 返回结果
return t;
}
}
时间转换类 将String类型的转换为 Date 类型的
/**
*
* 指定一个接口,内部包含有转换方法
* S 代表原始类型,T代表目标类型
* @Author
*/
public interface Convert<S,T> {
/**
* 将原始类型转换为目标类型
* @param s
* @return
*/
T convert(S s);
}
具体时间<泛型>转换类泛型>
public class MyConvert implements Convert<String, Date> {
// 自己定义时间格式
private SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
@Override
public Date convert(String source) {
try {
return source==null?null:simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
测试类
public void test4() {
// 测试类
Map<String, String[]> params = new HashMap<>();
params.put("user_name", new String[]{"张三"});
params.put("password", new String[]{"小姐姐", "小哥哥", "小姐姐和小哥哥"});
params.put("user_id", new String[]{"11111"});
params.put("create_time", new String[]{"2016/10/16 10:10:10"});
// 注册时间 自定义时间
MyConvert myMyMyDataConvert = new MyConvert();
BeanUtilsTest.register(Date.class, myMyMyDataConvert);
// 进行封装
User user = BeanUtilsTest.fillObject(params, User.class);
System.out.println(user.toString());
}
如下便完成了类的基本参数封装.