BeanUtil故名思义就是操作Bean的工具,其实现原理就是采用了反射,在servlet处理请求参数,处理ResultSet数据中经常用到,在不用MVC框架下可以很大的优化代码
下面是一个例子:
Model user类:
public class User {
private int id;
private String username;
private String password;
private Date birthday;
String[] interest; //***************
//省略getter、setter
}
User u = new User();
BeanUtils.copyProperty(u, "username", "张三");
BeanUtils.copyProperty(u, "age", 1);
BeanUtils.copyProperty(u, "ddd", value);//User中没有这个属性不会执行赋值操作
此时无法拷贝日期,因为BeanUtils不支持Date类型自动转换,需要自己定义相应的转换器来完成转换
beanutils自动进行类型转换,不过支持类型有限,想转换其它类型用类型转换器, 支持类型如下:
java.lang.BigDecimal、java.lang.BigInteger、boolean and java.lang.Boolean、byte and java.lang.Byte、char and java.lang.Character、java.lang.Class、double and java.lang.Double、float and java.lang.Float、int and java.lang.Integer、long and java.lang.Long、short and java.lang.Short、java.lang.String、java.sql.Date、java.sql.Time、java.sql.Timestamp
注意,java.util.Date不支持,而它的子类java.sql.Date是被支持的。
包中有BeanUtils、PropertyUtils工具类,主要的区别在于后者提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而前者不支持这个功能,但是效率好一些
BeanUtils可以直接get和set一个属性的值。它将property分成3种类型:
简单类型:如Stirng、Int……对于Simple类型,第二个参数直接是属性名即可
索引类型:如 数组、arrayList……对于Indexed,则为“属性名[索引值]”,注意这里对于ArrayList和数组都可以用一样的方式进行操作
Mape:指Map,比如HashMap……需要以“属性名(key值)”的形式
访问不同类型的数据可以直接调用函数getProperty和setProperty。它们都只有2个参数,第一个是JavaBean对象,第二个是要操作的属性名。
下面是一个应用:
前台显示代码:
<form action="/myTest/UserServlet?method=add" method="post">
用户名:<input type="text" name="username"/> <br>
密码:<input type="password" name="password"/> <br>
生日:<input type="text" name="birthday"/> <br>
兴趣:足球<input type="checkbox" name="interest" value="足球">篮球<input type="checkbox" name="interest" value="篮球"> <br>
<input type="submit" value="注册"/>
</form>
定义转换器的步骤
1、创建一个类让其实现Converter接口
2、覆盖这个接口中的convert方法,在这个方法中实现转换
3、在拷贝属性之前注册转换器
日期转换器DateConverter:
public class DateConverter implements Converter {
/**
* 该方法中的两个参数,第一个参数表示要转换的类型,如果要拷贝一个字符串到日期中,此时这个类型
* 就是日期类型,第二个参数表示要转换的值该方法的返回值就是转换之后的值
*/
@Override
public Object convert(Class clz, Object o) {
if(clz!=Date.class||!(o instanceof String)||o.equals(""))
return null;
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
Date date=null;
try {
date=sf.parse((String)o);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
使用beanUtil封装参数:
public class RequestUtil {
public static Object setParam(Class clz,HttpServletRequest req){
ConvertUtils.register(new DateConverter(), Date.class);
Map<String,String[]> m=req.getParameterMap(); //***注意返回的类型
Object o=null;
try {
o=clz.newInstance();
BeanUtils.populate(o, m);//也可以 用BeanUtils.copyProperties(o, m);
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
}
在servlet层使用RequestUtil接收参数:
User u=(User) RequestUtil.setParam(User.class, req);
很方便吧。在这个工具包中还有很多应用,比如处理结果集ResultSet,这些可以自己去发觉,重点是自己查看源代码,看看怎么实现的……
大致的实现过程应该是这样的,这里并没有处理类型转换:
Map<String,String[]> params=req.getParameterMap();
Set<String> keys=params.keySet();
User u=new User();
for(String key:keys){
String mk="set"+key.substring(0,1).toUpperCase()+key.substring(1);
Method m;
try {
m=u.getClass().getMethod(mk, String.class);//获取相应的set方法以便注入
m.invoke(u, params.get(key)[0]);
} catch (Exception e) {
e.printStackTrace();
}
}