package com.eip.common.util;import cn.hutool.core.util.ReflectUtil;import com.beust.jcommander.internal.Lists;import com.eip.common.annotation.FieldName;import com.google.common.collect.Maps;import com.google.gson.Gson;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang.StringUtils;import org.springframework.jdbc.core.JdbcTemplate;import javax.persistence.Column;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.math.BigDecimal;import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Objects;/** * 反射工具类 * */@Slf4jpublic class ReflectionUtils extends ReflectUtil { /** * 获取Object对象,所有成员变量属性值 */ public static HashMap<String, Object> getObjAttr(Object obj) { return getObjAttr(null, obj); } /** * 获取Object对象,所有成员变量属性值 */ public static HashMap<String, Object> getObjAttr(String prefix, Object obj) { if (obj == null) return Maps.newHashMap(); Field[] fields = obj.getClass().getDeclaredFields(); HashMap<String, Object> map = Maps.newHashMap(); int count = 0; for (Field field : fields) { // 对于每个属性,获取属性名 String varName = field.getName(); try { boolean access = field.isAccessible(); if (!access) { field.setAccessible(true); } //反射获取所有成员变量值 Object o = field.get(obj); if (PublicUtil.isNotEmpty(o)) count++; if (StringUtils.isNotBlank(prefix)) map.put(prefix + "_" + varName, o); if (StringUtils.isBlank(prefix)) map.put(varName, o); if (!access) { field.setAccessible(false); } } catch (Exception ex) { ex.printStackTrace(); } } return count > 0 ? map : null; } /** * 判断该对象是否 * @param obj 返回ture表示所有属性为null返回false表示不是所有属性都是null * @return */ public static boolean isAllFieldNull(Object obj) { boolean flag = true; try { Class stuCla = (Class) obj.getClass();//得到类对象 Field[] fs = stuCla.getDeclaredFields();//得到属性集合 for (Field f : fs) {//遍历属性 f.setAccessible(true);//设置属性是可以访问的(私有的也可以) Object val = f.get(obj); if (val != null) {//只要有1个属性不为空,那么就不是所有的属性值都为空 flag = false; break; } } } catch (IllegalAccessException e) { e.printStackTrace(); } return flag; } /** * 比较两个类型一样的对象中的值变更返回字符串 * * @param pre 变化前的对象 * @param last 变化后的对象 * @param fileIds 需要比对的字段 all为全部 * @param orgNum 查询需要机构号时传入 * @return * @apiNote 配合@FieldName注解一起使用 */ public static String compareObjectDifferentAttributes(Object pre, Object last, String fileIds, Integer orgNum) { if (StringUtils.isBlank(fileIds)) fileIds = "all"; List<String> fileIdList = Arrays.asList(fileIds.split(",")); StringBuilder result = new StringBuilder(); Class<?> preClass = pre.getClass(); Class<?> lastClass = last.getClass(); if (!preClass.equals(lastClass)) throw new RuntimeException("两个对象类型不一致"); Field[] declaredFields = preClass.getDeclaredFields(); for (Field field : declaredFields) { //获取方法名 String fieldName = field.getName(); if (!"all".equalsIgnoreCase(fileIds) && !fileIdList.contains(fieldName)) continue; try { //没有注解跳过比较 if (!field.isAnnotationPresent(FieldName.class)) continue; FieldName fieldAnno = field.getAnnotation(FieldName.class); boolean access = field.isAccessible(); String type = field.getType().getName(); if (!access) field.setAccessible(true); Object preValue = field.get(pre); Object lastValue = field.get(last); if ("".equals(preValue)) preValue = null; if ("".equals(lastValue)) lastValue = null; //BigDecimal 类型的数据要去掉小数点后尾部的0不一致造成数据比对差异 if ("java.math.BigDecimal".equals(type) && preValue != null && lastValue != null) { BigDecimal valOldBig = new BigDecimal(String.valueOf(preValue)); BigDecimal valNewBig = new BigDecimal(String.valueOf(lastValue)); //由于无法获取精度值,只能对所有带小数点的数据进行处理 if (String.valueOf(valOldBig).contains(".") || String.valueOf(valNewBig).contains(".")) { DecimalFormat formatter1 = new DecimalFormat("0.00"); preValue = formatter1.format(valOldBig); lastValue = formatter1.format(valNewBig); } } //DATE 类型的数据要格式化 if ("java.util.Date".equals(type)) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (preValue != null) preValue = sdf.format(preValue); if (lastValue != null) lastValue = sdf.format(lastValue); } //如果前后两个值都是空,那么无需比较 if (Objects.isNull(preValue) && Objects.isNull(lastValue)) { continue; } else if (Objects.isNull(preValue) && Objects.nonNull(lastValue)) { //前值为空,后值不为空 if (fieldAnno.isForeignKey()) { lastValue = getForeignKeyName(fieldAnno.sql(), lastValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam()); }else if(fieldAnno.isSysKey()){ lastValue = getSysKeyValue(fieldAnno.sysKey() ,lastValue); } result.append("'").append(fieldAnno.name()).append("'").append("由'空'变为").append("'").append(lastValue).append("'").append("\r\n"); } else if (Objects.nonNull(preValue) && Objects.isNull(lastValue)) {//前值不为空,后值为空 if (fieldAnno.isForeignKey()) { preValue = getForeignKeyName(fieldAnno.sql(), preValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam()); }else if(fieldAnno.isSysKey()){ preValue = getSysKeyValue(fieldAnno.sysKey() ,preValue); } result.append("'").append(fieldAnno.name()).append("'").append("由").append("'").append(preValue).append("'").append("变为'空'").append("\r\n"); } else if (Objects.nonNull(preValue) && Objects.nonNull(lastValue)) { //两个都不为空 if (preValue.equals(lastValue)) continue; //是否外键 if (fieldAnno.isForeignKey()) { preValue = getForeignKeyName(fieldAnno.sql(), preValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam()); lastValue = getForeignKeyName(fieldAnno.sql(), lastValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam()); }else if(fieldAnno.isSysKey()){ preValue = getSysKeyValue(fieldAnno.sysKey() ,preValue); lastValue = getSysKeyValue(fieldAnno.sysKey() ,lastValue); } result.append("'").append(fieldAnno.name()).append("'").append("由").append("'") .append(preValue).append("'").append("变为").append("'").append(lastValue).append("'").append("\r\n"); } if (!access) field.setAccessible(false); } catch (IllegalAccessException e) { e.printStackTrace(); } } return result.toString(); } /** * 查询系统定义的值 * @param sysKey * @param value * @return */ @SuppressWarnings("unchecked") public static String getSysKeyValue(String sysKey ,Object value) { if(StringUtils.isBlank(sysKey))return value.toString(); try { Map<String, String> map = Maps.newHashMap(); map = new Gson().fromJson(sysKey, map.getClass()); return map.get(value.toString())==null?value.toString():map.get(value.toString()); } catch (Exception e) { return value.toString(); } } /** * 查询外键所对应的名称 * * @param sql * @param value * @param isOrgNum * @return */ public static String getForeignKeyName(String sql, Object value, boolean isOrgNum, Integer orgNum,boolean isStringParam) {// Preconditions.checkArgument(StringUtils.isNotBlank(sql), "sql不能为空!"); if (StringUtils.isBlank(sql)) return ""; try { JdbcTemplate bean = ApplicationContextHolder.getBean(JdbcTemplate.class); Object[] args ; if(isStringParam){ args = new Object[]{value.toString()}; }else{ args = new Object[]{Integer.valueOf(value.toString())}; } if (isOrgNum) { sql += " and f_org_num = ?"; if(isStringParam){ args = new Object[]{value.toString(), orgNum}; }else{ args = new Object[]{Integer.valueOf(value.toString()), orgNum}; } } return bean.queryForObject(sql, args, String.class); } catch (Exception e) { return "空"; } } /** * 解析方法注解 * * @param clazz */ public static String getAnnotationAttribute(Class<?> clazz, String attributeField) { for (Field field : clazz.getDeclaredFields()) { if (field.getName().equalsIgnoreCase(attributeField) && field.isAnnotationPresent(Column.class)) { Column column = field.getAnnotation(Column.class);// System.out.println(column.name()); return column.name(); } } return null; } /** * 获取字段属性 * * @param clazz * @param attributeField * @return */ public static String getFieldType(Class<?> clazz, String attributeField) { for (Field field : clazz.getDeclaredFields()) { if (field.getName().equalsIgnoreCase(attributeField)) { return field.getType().toString(); } } return null; } /** * 获取字段名称 * @param clazz * @param ignoreFields * @return */ public static String[] getFieldName(Class<?> clazz, String ignoreFields) { if(ignoreFields==null)ignoreFields=""; List<String> list = Lists.newArrayList(); for (Field field : clazz.getDeclaredFields()) { if (!ignoreFields.contains(field.getName())) { list.add(field.getName()); } } return list.stream().toArray(String[]::new); } /** * 通过反射实现get方法 * @param o 要操作类的对象 * @param args 属性名 * @param <T> * @return * @throws NoSuchFieldException */ public static <T> T getMethod(T o,String args) throws NoSuchFieldException { Class cls = o.getClass(); //判断该属性是否存在 Field field = cls.getDeclaredField(args); if(field == null){ field = cls.getField(args); } if(field == null){ return (T)""; } String fieldName = "get"+args.substring(0,1).toUpperCase()+(args.length()>1?args.substring(1):""); Method method; try { method = cls.getMethod(fieldName); //Boolean返回 true是 false否 if(getFieldType(cls,args).equals("class java.lang.Boolean")){ Boolean invoke = (Boolean)method.invoke(o); return invoke.equals(true) ?(T)"是" :(T)"否"; } //Date返回 yyyy-MM-dd else if (getFieldType(cls,args).equals("class java.util.Date")){ if(method.invoke(o)!=null){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String date = sdf.format(method.invoke(o)); return (T)date; } } return (T)method.invoke(o); } catch (NoSuchMethodException e) { log.error(e.getMessage()); } catch (IllegalAccessException e) { log.error(e.getMessage()); } catch (InvocationTargetException e) { log.error(e.getMessage()); } return (T)""; }}