`
javamonkey
  • 浏览: 169633 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

修改后的BeanUtil更好的支持List Set 映射

阅读更多
通常从HTTPRequest中,可以通过BeanUtil自动将request中的参数映射到某个pojo中,如
BeanUtil.populate(request.getParameterMap(), obj);
但当客户端提交的form参数如下时,会出现问题
detail[0].name='123'&detail[0].age=14

另外,如果服务器端obj的属性是Set而不是List,则BeanUtil不支持

我实现了PropertyUtilsBean2,避免了上述问题
如下使用

Map map = new HashMap();
		map.put("code", "11212");
		map.put("amount", "1222222");
		map.put("details[0].vendorName", "vender");
		map.put("details[0].updateDate", "2001-1-1");
		map.put("details[1].vendorName", "vender33");
		map.put("details[1].updateDate", "2001-1-5");

		Order order = new Order();
		ConvertUtilsBean convertBean = new ConvertUtilsBean();
		
		BeanUtilsBean util = new BeanUtilsBean(convertBean,new PropertyUtilsBean2() );
		try {
			util.populate(order, map);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
		System.out.println(order.getAmount());
		System.out.println(order.getDetails().size());



代码如下,关键部分是getIndexedProperty方法里的
if ((value instanceof java.util.Set)){}
else if (value instanceof java.util.List){}
/**
 * 对原有PropertyUtilsBean,进行了改善,增强了对list映射,增加set的映射支持,参考getIndexedProperty方法
 * @author lijiaz
 *
 */
public class PropertyUtilsBean2 extends PropertyUtilsBean {
	public PropertyUtilsBean2() {
		super();
	}

	private Object invokeMethod(Method method, Object bean, Object[] values)
			throws IllegalAccessException, InvocationTargetException {
		if (bean == null) {
			throw new IllegalArgumentException(
					"No bean specified "
							+ "- this should have been checked before reaching this method");
		}

		try {

			return method.invoke(bean, values);

		} catch (NullPointerException cause) {
			// JDK 1.3 and JDK 1.4 throw NullPointerException if an argument is
			// null for a primitive value (JDK 1.5+ throw IllegalArgumentException)
			String valueString = "";
			if (values != null) {
				for (int i = 0; i < values.length; i++) {
					if (i > 0) {
						valueString += ", ";
					}
					if (values[i] == null) {
						valueString += "<null>";
					} else {
						valueString += (values[i]).getClass().getName();
					}
				}
			}
			String expectedString = "";
			Class[] parTypes = method.getParameterTypes();
			if (parTypes != null) {
				for (int i = 0; i < parTypes.length; i++) {
					if (i > 0) {
						expectedString += ", ";
					}
					expectedString += parTypes[i].getName();
				}
			}
			IllegalArgumentException e = new IllegalArgumentException(
					"Cannot invoke " + method.getDeclaringClass().getName()
							+ "." + method.getName() + " on bean class '"
							+ bean.getClass() + "' - "
							+ cause.getMessage()
							// as per https://issues.apache.org/jira/browse/BEANUTILS-224
							+ " - had objects of type \"" + valueString
							+ "\" but expected signature \"" + expectedString
							+ "\"");
			if (!BeanUtils.initCause(e, cause)) {

			}
			throw e;
		} catch (IllegalArgumentException cause) {
			String valueString = "";
			if (values != null) {
				for (int i = 0; i < values.length; i++) {
					if (i > 0) {
						valueString += ", ";
					}
					if (values[i] == null) {
						valueString += "<null>";
					} else {
						valueString += (values[i]).getClass().getName();
					}
				}
			}
			String expectedString = "";
			Class[] parTypes = method.getParameterTypes();
			if (parTypes != null) {
				for (int i = 0; i < parTypes.length; i++) {
					if (i > 0) {
						expectedString += ", ";
					}
					expectedString += parTypes[i].getName();
				}
			}
			IllegalArgumentException e = new IllegalArgumentException(
					"Cannot invoke " + method.getDeclaringClass().getName()
							+ "." + method.getName() + " on bean class '"
							+ bean.getClass() + "' - "
							+ cause.getMessage()
							// as per https://issues.apache.org/jira/browse/BEANUTILS-224
							+ " - had objects of type \"" + valueString
							+ "\" but expected signature \"" + expectedString
							+ "\"");
			if (!BeanUtils.initCause(e, cause)) {

			}
			throw e;

		}
	}
	
	Method getReadMethod(Class clazz, PropertyDescriptor descriptor) {
        return (MethodUtils.getAccessibleMethod(clazz, descriptor.getReadMethod()));
    }

	public Object getIndexedProperty(Object bean, String name, int index)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {

		if (bean == null) {
			throw new IllegalArgumentException("No bean specified");
		}
		if (name == null || name.length() == 0) {
			if (bean.getClass().isArray()) {
				return Array.get(bean, index);
			} else if (bean instanceof List) {
				return ((List) bean).get(index);
			}
		}
		if (name == null) {
			throw new IllegalArgumentException(
					"No name specified for bean class '" + bean.getClass()
							+ "'");
		}

		// Handle DynaBean instances specially
		if (bean instanceof DynaBean) {
			DynaProperty descriptor = ((DynaBean) bean).getDynaClass()
					.getDynaProperty(name);
			if (descriptor == null) {
				throw new NoSuchMethodException("Unknown property '" + name
						+ "' on bean class '" + bean.getClass() + "'");
			}
			return (((DynaBean) bean).get(name, index));
		}

		// Retrieve the property descriptor for the specified property
		PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
		if (descriptor == null) {
			throw new NoSuchMethodException("Unknown property '" + name
					+ "' on bean class '" + bean.getClass() + "'");
		}

		// Call the indexed getter method if there is one
		if (descriptor instanceof IndexedPropertyDescriptor) {
			Method readMethod = ((IndexedPropertyDescriptor) descriptor)
					.getIndexedReadMethod();
			readMethod = MethodUtils.getAccessibleMethod(bean.getClass(),
					readMethod);
			if (readMethod != null) {
				Object[] subscript = new Object[1];
				subscript[0] = new Integer(index);
				try {
					return (invokeMethod(readMethod, bean, subscript));
				} catch (InvocationTargetException e) {
					if (e.getTargetException() instanceof IndexOutOfBoundsException) {
						throw (IndexOutOfBoundsException) e
								.getTargetException();
					} else {
						throw e;
					}
				}
			}
		}

		// Otherwise, the underlying property must be an array
		Method readMethod = getReadMethod(bean.getClass(), descriptor);
		if (readMethod == null) {
			throw new NoSuchMethodException("Property '" + name + "' has no "
					+ "getter method on bean class '" + bean.getClass() + "'");
		}

		// Call the property getter and return the value
		Object value = invokeMethod(readMethod, bean, new Object[0]);
		

		if (!value.getClass().isArray()) {
			if ((value instanceof java.util.Set)) {
				//Set并不支持通过index来获取,所以必须循环,导致有些效率问题,然后对于目前应用来说问题并不大
				Set set = (java.util.Set) value;
				Type returnType = readMethod.getGenericReturnType();
				Type acturalType = ((ParameterizedType)returnType).getActualTypeArguments()[0];
				
				
				while(set.size()<=index){
					try {
						set.add(((Class)acturalType).newInstance());
					} catch (InstantiationException e) {
						throw new RuntimeException(e.getMessage());
					}
				}
				Iterator it = set.iterator();
				int i=0;
				Object o = null;
				while(i<=index){
					it.hasNext();
					o = it.next();
					i++;
				}
				return o;
				
			} else if (value instanceof java.util.List){
				// get the List's value
				List list = (java.util.List) value;
				Type returnType = readMethod.getGenericReturnType();
				Type acturalType = ((ParameterizedType)returnType).getActualTypeArguments()[0];
				
				
				while(list.size()<=index){
					try {
						list.add(((Class)acturalType).newInstance());
					} catch (InstantiationException e) {
						throw new RuntimeException(e.getMessage());
					}
				}
				return list.get(index);
			}
			else{
				throw new IllegalArgumentException("Property '" + name
						+ "' is not indexed on bean class '" + bean.getClass()
						+ "'");
			}
		} else {
			// get the array's value
			try {
				return (Array.get(value, index));
			} catch (ArrayIndexOutOfBoundsException e) {
				throw new ArrayIndexOutOfBoundsException("Index: " + index
						+ ", Size: " + Array.getLength(value)
						+ " for property '" + name + "'");
			}
		}

	}
}




1
1
分享到:
评论
1 楼 xzcgeorge 2012-12-08  
Good Job!

But I found a problem.  Try this:

        map.put("details[0]", "vender");  
        map.put("details[1]", "vender33");  
That is, change the List of details from a class to a String list:

List<String> details = new ArrayList<String>();

you will get an error:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 0

Any idea?

Thanks!

相关推荐

    beanutil数据库操作工具

    1. **对象属性填充**:当从数据库查询到结果集后,BeanUtil能够将这些结果自动映射到预先定义好的Java Bean对象中,无需手动一一赋值。这大大减少了代码量,提高了代码的可读性和可维护性。 2. **对象到Map的转换**...

    BeanUtil框架完整包

    BeanUtil框架是一个在Java开发中常用的工具库,主要用于对象属性的获取、设置、拷贝以及类型转换等操作。它的设计目标是简化Java Bean...但在使用时,开发者也需要了解其工作原理和潜在的问题,以便更好地应用和维护。

    BeanUtil Jar包

    1. **属性的读写操作**:BeanUtil提供了`getProperty()`和`setProperty()`方法,使得我们可以无需关心具体的getter和setter方法,只需知道属性名,即可实现对象属性的获取和设置。例如,通过`BeanUtil.setProperty...

    BeanUtil_Jar包

    本文将深入探讨BeanUtil_Jar包的核心特性和使用方法,帮助开发者更好地理解和应用这个经典库。 首先,让我们了解什么是JavaBean。JavaBean是一种符合特定规范的Java类,通常用来封装数据并提供公共方法来访问这些...

    BeanUtil属性拷贝工具类

    BeanUtil属性拷贝工具类,支持基本的javabean属性拷贝,通过java反射和泛型编程实现了list属性拷贝

    BEANutil工具类,可获取生日

    BEANutil工具类,可获取生日,简单的几行代码,给需要的你。BEANutil工具类,可获取生日,简单的几行代码,给需要的你。

    改进的BeanUtil包

    修改内容: 1.org.apache.commons.beanutils.converters包下增加了UtilDateConverter类 2.修改了org.apache.commons.beanutils.converters包下的StringConverter类 3.ConvertUtilsBean类中的public void ...

    BeanUtil.java

    BeanUtil.java

    BeanUtil工具类

    BeanUtil 主要用于实体Bean和Map之间的互转,使用方便,是一个不可多得的工具类哦

    beanutil

    beanutil的的jar包 大家顶啦

    BeanUtil.rar

    BeanUtil需要的jar包和源码文件,commons-beanutils-1.8.0.jar,commons-beanutils-1.8.0-javadoc.jar,commons-beanutils-1.8.0-sources.jar,commons-beanutils-bean-collections-1.8.0.jar,commons-beanutils-...

    BeanUtil1.8 SRC 源码和 jar包

    《BeanUtil1.8源码与jar包...在实际开发过程中,掌握BeanUtil的使用不仅可以提升开发效率,还能更好地理解和应用Java Bean的设计模式。无论是作为开发工具,还是学习资料,BeanUtil1.8都是Java开发者不可或缺的资源。

    common-beanutil源代码

    common-beanutil的源代码 1.8.1

    apache beanutil_1.8.3_API

    beanutil_1.8.3_API

    BeanUtil_MYSQL_mybaatis_

    DDL语句用来定义数据库的结构,如创建、修改和删除表。DML语句则用于操纵数据库中的数据,包括INSERT(插入)、UPDATE(更新)、DELETE(删除)和SELECT(查询)。 BeanUtil类,根据名字推测,可能是实现了将Java ...

    BeanUtil与Logging

    - **反射操作**:`BeanUtils.getProperty()`和`BeanUtils.setProperty()`可以方便地通过字符串形式的属性名来访问和修改JavaBean的属性,简化了反射操作。 - **类型转换**:BeanUtils还处理了基本类型和包装类型的...

    beanutil的jar包打包

    此外,它还包含了一些特殊的集合实现,如双向映射、多值映射等。 4. **Apache Commons Logging**:作为一个日志适配器,它允许程序在运行时选择使用哪种日志实现,比如切换从System.out.println到Log4j,只需要改变...

    Servlet中对获取网页表单数据自动给JavaBean赋值的BeanUtil工具类

    总的来说,BeanUtil工具类是Java Web开发中的实用工具,它简化了Servlet处理表单数据和JavaBean之间数据转换的过程,让代码更简洁、更易于维护。在学习和使用BeanUtil时,还需要了解其潜在的类型转换问题和安全性...

    commons-beanutil-1.7.0-src

    这个"commons-beanutil-1.7.0-src"压缩包包含了BeanUtils库的源代码,版本号为1.7.0,是开发者理解和自定义此库功能的重要资源。以下是关于Apache Commons BeanUtils库及其1.7.0版本的一些关键知识点: 1. **...

    beanutil源代码

    总的来说,"beanutil源代码"和"fileupload"都是Java Web开发中的实用工具,前者简化了JavaBean对象的交互,后者则提供了强大的文件上传处理能力。将两者结合,可以高效地实现复杂的业务逻辑,如用户上传文件并保存...

Global site tag (gtag.js) - Google Analytics