分享一个比较好用的Java工具类PropertyUtility,方便处理前端参数接收和实体类映射,可以全复制类属性,非空类属性,节约很多不必要的get和set的代码

本文介绍了Java工具类PropertyUtility,用于高效地处理对象属性的复制、设置和获取。该工具类能节省手动get和set的时间,适用于接收前端参数并映射到数据库实体类的场景。文章提供了详细代码示例,包括从对象转换为字符串、列表转换、属性复制等方法,以及如何根据业务需求灵活使用。
摘要由CSDN通过智能技术生成

说明:这玩意不比BeanUtils快,而且

所花费的时间要超过取数 据、将其复制到对应的 value对象(通过手动调用get和set方法),以及通过串行化将其返回到远程的客户机的时间总和。但是也很快了,具体请根据你的业务需求使用

一个常见场景

web前端框架接收一个post请求,参数比较多,我们单独创建一个Vo用于接收

接收之后,需要将这些参数直接或者逻辑处理后设置进与数据库映射的实体类,再保存入数据库

那些不需要处理的参数,可以直接复制过来,不需要一个一个get和set处理,节约代码和时间

上工具类代码

PropertyUtility.java

其中有注释和源码,可以仔细阅读和尝试使用,验证其功效



import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import dev.fpxgroup.common.utility.DateParser;
import dev.fpxgroup.common.utility.DateUtility;
import dev.fpxgroup.common.utility.StringUtility;


/**
 * 对象属性的公共方法
 *
 * Author: lijinquan
 * Created Time: 2017-06-03
 */
public final class PropertyUtility {
  private final static String SET = "set";
  private final static String GET = "get";
  public final static String ENTER = "\r\n";
  private final static String SPACE = " ";
  private final static String COLON = ":";
  private final static String TABS = "\t";
  private final static String DOTZERO = ".0";

  /**
   * 得到对象的ToString的内容
   *
   * @param obj Object
   * @param entered boolean
   * @return String
   */
  public static String getPropertyToString(Object obj, boolean entered) {
    if (obj == null)
      return "";

    if (isBroadPrimitive(obj.getClass()))
      return String.valueOf(obj);

    StringBuilder desc = new StringBuilder();
    desc.append(obj.getClass().getName()).append(TABS);
    try {
      Field[] aobjField = getDeclaredFields(obj.getClass());
      for (Field field : aobjField) {
        try {
          desc.append(SPACE + field.getName() + COLON);
          Object objValue = getProperty(obj, field.getName());
          desc.append(objValue);

          if (entered)
            desc.append(ENTER);
        } catch (Exception e) {
          //Do Nothing
        }
      }
    } catch (Exception e) {
      //Do Nothing
    }
    return desc.toString();
  }

  public static String getPropertyToString(Object obj) {
    return getPropertyToString(obj, false);
  }

  public static String getListToString(List list) {
	  StringBuffer buffer = new StringBuffer();
	  if(list != null && list.size() > 0 ){
		  for(Object ob : list ){
			  buffer.append(getPropertyToString(ob, true)+ENTER);;
		  }
	  }
    return buffer.toString();
  }
  /**
   * 是广义原子类型,即是字符串、原始类型或Box原始类型
   *
   * @param clzSource
   * @return
   */
  public static boolean isBroadPrimitive(Class clzSource) {
    if (clzSource == String.class || clzSource.isPrimitive() || isPrimitive(clzSource))
      return true;
    else
      return false;
  }

  /**
 * <p>@description  判断是否为Map</p> 
 * Author: lijinquan
 * Created Time: 2017-06-03
 * @lastModificationDate 2013-8-15
 * @remark 
 * @param clazz
 * @return
 */
public static boolean isMap(Class<?> clazz) {
	if (HashMap.class == clazz || LinkedHashMap.class == clazz) {
		return true;
	}
	return false;
}

/**
   * 判断是否为原始数据类型
   *
   * @param clzType Class
   * @return boolean
   */
  public static boolean isPrimitive(Class clzType) {
    if (clzType == Integer.class || clzType == Boolean.class || clzType == Float.class || clzType == Double.class
        || clzType == Short.class || clzType == Long.class || clzType == short.class || clzType == long.class
        || clzType == int.class || clzType == boolean.class || clzType == float.class || clzType == double.class) {
      return true;
    } else {
      return false;
    }
  }

  public static boolean isPrimitive(Object target, String property) {
    Class classX = getDeclaredFieldClass(target.getClass(), property);
    return isPrimitive(classX);
  }

  /**
   * 得到本类及其父类的所有属性
   * Author: lijinquan
   * Created Time: 2017-06-03
   * @param clzParse Class
   * @return Field[]
   */
  public static Field[] getDeclaredFields(Class clzParse) {
    Field[] aobjField = clzParse.getDeclaredFields();
    Field[] aobjFieldResult = aobjField;

    Class superClz = clzParse.getSuperclass();

    //用While循环替换递归调用
    //这里存在一个BUG,当父类有的属性子类也存在时,应该只保留子类的Field
    while (superClz != null) {
      Field[] aobjSuperField = superClz.getDeclaredFields();

      if (aobjSuperField != null && aobjSuperField.length > 0) {
        int srcLength = aobjFieldResult.length;
        aobjField = new Field[srcLength + aobjSuperField.length];
        System.arraycopy(aobjFieldResult, 0, aobjField, 0, srcLength);
        System.arraycopy(aobjSuperField, 0, aobjField, srcLength, aobjSuperField.length);
        aobjFieldResult = aobjField;
      }

      superClz = superClz.getSuperclass();
    }

    return aobjFieldResult;
  }

  /**
   * 得到本类和父类的字段的Class
   * Author: lijinquan
   * Created Time: 2017-06-03
   * @param clzParse Class
   * @param property String
   * @return Class
   */
  public static Class getDeclaredFieldClass(Class clzParse, String property) {
    Field[] arrField = getDeclaredFields(clzParse);
    for (Field field : arrField) {
      if (field.getName().equals(property))
        return field.getType();
    }
    return null;
  }

  public static void setPropertyIgnoreCase(Object dest, String property, Object value) throws Exception {
    Field[] arrField = getDeclaredFields(dest.getClass());
    for (Field elem : arrField) {
      if (elem.getName().equalsIgnoreCase(property)) {
        setProperty(dest, elem.getName(), value);
        break;
      }
    }
  }

  /**
   * 设置属性
   *
   * @param dest Object
   * @param property String
   * @param value Object
   * @throws Exception
   */
  public static void setProperty(Object dest, String property, Object value) throws Exception {
    if (dest == null || value == null || StringUtility.isNull(property))
      return;

    Class argumentType = getDeclaredFieldClass(dest.getClass(), property);

    Class[] aobjClass = {argumentType};
    String strFunction = SET + property.substring(0, 1).toUpperCase() + property.substring(1);

    Method objMethod = dest.getClass().getMethod(strFunction, aobjClass);
    objMethod.setAccessible(true);

    Object tranferValue = value;
    if (argumentType == Integer.class || argumentType == int.class) {
      tranferValue = Integer.parseInt(trimDotForInteger(value.toString()));
    } else if (argumentType == Float.class || argumentType == float.class) {
      tranferValue = Float.parseFloat(value.toString());
    } else if (argumentType == Boolean.class || argumentType == boolean.class) {
      tranferValue = Boolean.parseBoolean(value.toString());
    } else if (argumentType == Double.class || argumentType == double.class) {
      tranferValue = Double.parseDouble(value.toString());
    } else if (argumentType == Short.class || argumentType == short.class) {
      tranferValue = Short.parseShort(value.toString());
    } else if (argumentType == Long.class || argumentType == long.class ) {
      tranferValue = Long.parseLong(trimDotForInteger(value.toString()));
    } else if (argumentType == String.class) {
      tranferValue = value.toString();
    } else if (argumentType == String.class && value.getClass() == Date.class) {
      tranferValue = DateUtility.getDatetime((Date) value);
    } else if (argumentType == Date.class && value.getClass() == String.class) {
      tranferValue = new DateParser().parse((String) value);
    } else if (argumentType == BigDecimal.class) {
      tranferValue = BigDecimal.valueOf(Double.parseDouble(value.toString()));
    }


    // 构造执行参数
    Object[] aobjPD = {tranferValue};
    objMethod.invoke(dest, aobjPD);
  }

  /**
   * sValue为整形数据,后面有加了 .0, 需要将这个 .0去掉
   *
   * @param sValue String
   * @return String
   */
  private static String trimDotForInteger(String sValue) {
    if (sValue.endsWith(DOTZERO))
      sValue = sValue.substring(0, sValue.length() - DOTZERO.length());
    return sValue;
  }

  /**
   * 得到属性的值
   *
   * @param target Object
   * @param property String
   * @return Object
   * @throws Exception
   */
	public static Object getProperty(Object target, String property)
			throws Exception {
		if (target == null || property == null)
			return null;

		String strFunction = GET + property.substring(0, 1).toUpperCase()
				+ property.substring(1);
		Method objMethod = null;
		try {
			objMethod = target.getClass().getMethod(strFunction);
			objMethod.setAccessible(true);
			return objMethod.invoke(target);
		} catch (NoSuchMethodException e) {
//			e.printStackTrace();
		} catch (SecurityException e) {
		}

		return null;

	}

  /**
   * 将原对象里面的值copy到目标对象中,只是String -> 基本类型 和基本类型 ->String的转换
   * 原对象中存在空值也会copy
   *
   * @param desc Object
   * @param src Object
   * @throws Exception
   */
  public static void copyProperty(Object dest, Object src) throws Exception {
    _copyProperty(dest, src, true);
  }

  /**
   * 原对象中如果是空值就不会Copy
   *
   * @param dest Object
   * @param src Object
   * @throws Exception
   */
  public static void copyProperty2(Object dest, Object src) throws Exception {
    _copyProperty(dest, src, false);
  }

  /**
   * 将原对象中不为空的属性, copy到目标对象中。 如果目标对象中的该属性不为空就不copy.
   *
   * @param dest Object
   * @param src Object
   * @throws Exception
   */
  public static void copyProperty3(Object dest, Object src) throws Exception {
    Field[] destFields = getDeclaredFields(dest.getClass());
    Field[] srcFields = getDeclaredFields(src.getClass());
    for (Field field : destFields) {
      try {
        if (isExisted(field, srcFields)) {
          Object objsrcValue = getProperty(src, field.getName());
          Object objdestValue = getProperty(dest, field.getName());
          if (objsrcValue != null && objdestValue == null)
            setProperty(dest, field.getName(), objsrcValue);
        }
      } catch (Exception e) {
        System.err.println(e.getMessage());
      }
    }
  }

  private static void _copyProperty(Object dest, Object src, boolean nullCopyed) throws Exception {
    Field[] destFields = getDeclaredFields(dest.getClass()), srcFields = getDeclaredFields(src.getClass());
    Object objValue = null;
    for (Field field : destFields) {
      try {
        if (isExisted(field, srcFields)) {
          objValue = getProperty(src, field.getName());
          if (objValue != null || (objValue == null && nullCopyed))
            setProperty(dest, field.getName(), objValue);
        }
      } catch (Exception e) {
        System.err.println(e.getMessage());
      }
    }
  }

  /**
   * 判断字段是否存在于字段数组中
   *
   * @param field Field
   * @param allFields Field[]
   * @return boolean
   */
  private static boolean isExisted(Field field, Field[] allFields) {
    for (int i = 0; i < allFields.length; i++) {
      if (field.getName().equals(allFields[i].getName()))
        return true;
    }
    return false;
  }

  /**
   * 判断对象中是否存在指定的属性
   *
   * @param target Object
   * @param sProperty String
   * @return boolean
   */
  public static boolean isExisted(Object target, String sProperty) {
    return isExisted(target.getClass(), sProperty);
  }

  public static boolean isExisted(Class target, String sProperty) {
    Field[] destFields = getDeclaredFields(target);
    boolean result = false;
    for (int i = 0; i < destFields.length; i++) {
      if (destFields[i].getName().equals(sProperty)) {
        result = true;
        break;
      }
    }
    return result;

  }


  /**
   * 创建对象, 并将原对象里面的内容COPY到新对象中
   *
   * @param dest Class
   * @param src Object
   * @return Object
   * @throws Exception
   */
  public static Object createObject(Class dest, Object src) throws Exception {
    Object destObject = dest.newInstance();
    copyProperty(destObject, src);
    return destObject;
  }

	/**
	 * 复制原始对象属性到目标对象中
	 * @param dest
	 * @param src
	 * @param nullCopy 原始对象属性为空是否复制
	 * @param emptyFlag 如果#overrideForce 为true,此字段生效。若原始对象有emptyFlag值的字段,则将目标对象中该字段置为空
	 * @throws Exception
	 */
	public static void copyProperty4(Object dest, Object src,
			boolean nullCopy, String emptyFlag)
			throws Exception {
		Field[] destFields = getDeclaredFields(dest.getClass());
		Field[] srcFields = getDeclaredFields(src.getClass());
		Object objSrcValue = null;
		Object objdestValue = null;
		for (Field field : destFields) {

			if (isExisted(field, srcFields)) {
				objSrcValue = getProperty(src, field.getName());
				objdestValue = getProperty(dest, field.getName());
				
				if (nullCopy) {
					if (!StringUtility.isNull(emptyFlag)
							&& emptyFlag.equals(objSrcValue)) {
						objSrcValue = "";
					}
					setProperty(dest, field.getName(), objSrcValue);
				}else {
					if (!isEmpty(objSrcValue) ) {
						if (!StringUtility.isNull(emptyFlag)
								&& emptyFlag.equals(objSrcValue)) {
							objSrcValue = "";
						}
						setProperty(dest, field.getName(), objSrcValue);
					} 
				}
				
			}

		}
	}

	private static boolean isEmpty(Object obj) {
		if (obj==null) {
			return true;
		}
		if (obj instanceof String) {
			return obj == null||"".equals(obj.toString());
		}else if (obj instanceof Integer||obj instanceof Double||obj instanceof Long) {
			return obj==null||Double.parseDouble(obj.toString())==0;
		}
		return false;
	}

}

使用案例1:

准备两个实体类TuserVo.java

public class TUserVo extends Parameter implements Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

    //用户编号
	private  Integer urId;

	//年龄
	private  Integer age;


	//姓名
	private  String uaName;

    //生日

    private String birthday;



    @TODO get和set方法省略

}

和数据库映射的实体类

public class TUser extends Parameter implements Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

    //用户编号
	private  Integer urId;

	//年龄
	private  Integer age;


	//姓名
	private  String uaName;

    //生日

    private String birthday;


    //生肖
    private String zodiac;



    @TODO get和set方法省略

}

两个具备大多数相同属性的类型,可以复制

比如,我们接收参数的vo,复制进实体类,缺失或者需要逻辑处理的值,可以取出处理后单独set

/**
	 * 用户添加/编辑
	 *
	 * @return
	 * @throws Exception
	 * @return ResultVO<TUserAddress>
	 */
	@POST
	@Path("/addUser")
	@Produces({ "application/json" })
	public ResultVO<TUserVo> addUserAddress(@FormParam("") TUserVo parameter) throws Exception{


      @TODO 业务逻辑


}

假设TUserVo的很多属性和user一样,那先执行如下

TUser user=new TUser();

PropertyUtility.copyProperty3(user, userVo);

这样操作后,userVo和user相同属性复制到了user中

因为userVo作为前端接受参数的类型,属性更加多样和灵活,假如user实体类其中有一个属性用户生肖(zodiac),需要拿userVo传进来的生日进行运算

那完全可以在使用工具类复制后,单独再设置该值,满足业务需求

更多应用场景和功能,大家可以多动手动脑

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值