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

上篇博客中主要介绍了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的源码是也是利用内省的机制实现的。下一步会想办法证实一下。





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值