重写org.springframework.beans.BeanUtils的copyProperties(Object source,Object target)方法 从model复制属性到pojo中

当一个对象中有几十个字段,而我们修改该对象信息时,可能只修改其中的几个或十几个,通过spring的BeanUtils的copyProperties方法将model复制到pojo时,会将model中的null属性也全部复制到了pojo中,这样原来不想修改的属性变为了null,这不是我们想要的。

当然可以通过get从model中取出要修改的属性,然后再set到pojo中,但这样比较麻烦。

所以自己新建一个BeanUtils类,继承org.springframework.beans.BeanUtils类,覆盖copyProperties(Object source, Object target)方法,重写copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)方法,从model复制属性到pojo中时,model中为null的属性不复制pojo中。


重写代码:

package com.goldweb.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
 * 重写 org.springframework.beans.BeanUtils 的 copyProperties(Object source, Object target) 方法
 * 从model复制属性到pojo中时,model中为null的属性不复制pojo中
 * @author liangshishen
 *
 */
public abstract class BeanUtils extends org.springframework.beans.BeanUtils {

	/**
	 * 从org.springframework.beans.BeanUtils类中直接复制过来
	 * @param source
	 * @param target
	 * @throws BeansException
	 */
	public static void copyProperties(Object source, Object target) throws BeansException {
		copyProperties(source, target, null, (String[]) null);
	}
	
	/**
	 * 从org.springframework.beans.BeanUtils类中直接复制过来,修改部分代码
	 * @param source
	 * @param target
	 * @param editable
	 * @param ignoreProperties
	 * @throws BeansException
	 */
	private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)
			throws BeansException {

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");

		Class<?> actualEditable = target.getClass();
		if (editable != null) {
			if (!editable.isInstance(target)) {
				throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
						"] not assignable to Editable class [" + editable.getName() + "]");
			}
			actualEditable = editable;
		}
		PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
		List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;

		for (PropertyDescriptor targetPd : targetPds) {
			Method writeMethod = targetPd.getWriteMethod();
			if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
				PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
				if (sourcePd != null) {
					Method readMethod = sourcePd.getReadMethod();
					if (readMethod != null &&
							ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
						try {
							if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
								readMethod.setAccessible(true);
							}
							Object value = readMethod.invoke(source);
							// 判断被复制的属性是否为null, 如果不为null才复制
							if (value != null) {
								if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
									writeMethod.setAccessible(true);
								}
								writeMethod.invoke(target, value);
							}
						}
						catch (Throwable ex) {
							throw new FatalBeanException(
									"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
						}
					}
				}
			}
		}
	}
	
}

使用:

	public boolean updateUser(UserModel userModel) {
		if (userModel != null) {
			User user = new User();
			// 为了不与spring的BeanUtils冲突, 这里用全名调用自定义的BeanUtils
			// 这样userModel中为null的属性将不会复制到user中, user中没有修改的属性还保持原来的, 不会被复制为null了
			com.goldweb.utils.BeanUtils.copyProperties(userModel, user);
			// 更新用户
			userDAO.merge(user);
			return true;
		}
		return false;
	}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值