您的位置:首页 > 其它

深入理解J2SE—Introspector(内省)应用

2016-05-23 21:25 513 查看
上篇博客中主要介绍了Introspector的使用方法和概念,这篇博客中主要来写一些Introspector的应用。为什么要利用Introspector来对javabean进行get/set值,而不直接使用get/set方法。

例如。现在有一个User javabean。表单向后台服务器提交数据时,从表单中获取的数据会设置到User javabean中。然后利用User对象进行业务逻辑处理。

package com.ray.javaneisheng;

import java.util.Date;

public class User {
private String name;
private String password;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [name=" + name + ", password=" + password + "]";
}

}


1.一般情况下可以会利用request.getParameter()方法将数据设置到User对象中。此种方法比较繁琐,如果javabean对象中属性有多个,那每一个都要设置,这种方法显然是不够灵活,并且效率低。

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// User u = populate(User.class,request.getParameterMap());
User u = new User();
u.setName(request.getParameter("name"));
u.setPassword(request.getParameter("password"));
System.out.println(u);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


2.上一篇文章中可以利用Introspector来操作和管理javabean的get/set方法。那这里我们也利用Introspector和request.getParameterMap()将表单中的数据,全部设置到user对象中。此种方法有有一个弊端只能支持String类型的变量。写的不够灵活,但是能体现出可以利用Introspector来灵活操作javabean的思想。

public class LoginServlet extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
User u = populate(User.class,request.getParameterMap());
System.out.println(u);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/**
* 利用java内省来将parameterMap中的值放入到javabean对象中
*/
private User populate(Class<User> class1, Map<String, String[]> parameterMap)
throws Exception, IllegalAccessException {
// 创建出user对象
User u = class1.newInstance();
BeanInfo info = Introspector.getBeanInfo(u.getClass());
PropertyDescriptor[] propertyDescriptors = info
.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
String[] params = parameterMap.get(propertyDescriptor.getName());
if (params != null && params.length > 0) {
propertyDescriptor.getWriteMethod().invoke(u, params[0]);
}
}
return u;
}


3.利用apache 提供了.commons-beanutils来将表单提交上来的内容设置到javabean中,这种方法同样是传入的参数ParameterMap。这种方法在封装的时候自动进行类型转化,但是只能在8个基本数据类型中转换。

public class LoginServlet extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
User u = new User();
// BeanUtils 的 该方法还可以自动进行类型转换. 只能转换8中基本数据类型.
BeanUtils.populate(u, request.getParameterMap());
System.out.println(u);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
如果我们在 User javabean对象中加入了Date类型的属性,例如加入private Date birthday,并且提供get,set方法。这时在使用BeanUtils.populate方法时会抛出argument type mismatch异常。这种原因是BeanUtils.populate方法只支持8个基本数据类型中的转换。如果需要转换其他类型需要提供类型转化器,自定义转换规则。

public class MyConverter implements Converter {
 
// 参数2 就是 将要被转换的String  ==>  1990-12-12
// 参数1 提示你要把 参数2转换成什么类型的. ==>   Date
public Object convert(Class arg0, Object obj) {
SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd");
try {
return format.parse(obj.toString());
} catch (Exception e) {
throw new RuntimeException("类型转换失败");
}
}
 
}

并将该转换类注册

public class LoginServlet extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
User u = new User();
// BeanUtils 的 该方法还可以自动进行类型转换. 只能转换8中基本数据类型.
// 注册一个转换器, 来转换自定义类型
ConvertUtils.register(new MyConverter(), Date.class);
BeanUtils.populate(u, request.getParameterMap());
System.out.println(u);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}

以上就是内省的应用。这种方式很显然的更加方便的操作了javabean,尤其是提现在表单提交时间,后台服务器获取这些数据时。

我在猜测一件事就是BeanUtils.populate的源码是也是利用内省的机制实现的。下一步会想办法证实一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: