package com.vci.starter.web.util; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.lang.Snowflake; import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.vci.common.exception.VciExceptionTool; import com.vci.corba.common.PLException; import com.vci.starter.web.annotation.Id; import com.vci.starter.web.annotation.VciBtmType; import com.vci.starter.web.annotation.VciLinkType; import com.vci.starter.web.enumpck.BooleanEnum; import com.vci.starter.web.enumpck.UserSecretEnum; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.pagemodel.SessionInfo; import com.vci.starter.web.toolmodel.DateConverter; import com.vci.starter.web.wrapper.VciQueryWrapperForDO; import freemarker.cache.StringTemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; import org.springframework.util.ResourceUtils; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 基础的工具类 * @author weidy */ public class VciBaseUtil { /** * 获取异常信息,因为抛出的异常不同,获取错误信息的方式存在差异所以无法统一获取 * 后续有其他异常需要获取,自行添加处理逻辑, * @param e * @return */ public static String getExceptionMessage(Throwable e){ String exceptionStr = VciExceptionTool.getExceptionStr(e); if(exceptionStr.contains("VciBaseException")){ return e.getMessage(); }else if(exceptionStr.contains("PLException")){ return Arrays.stream(((PLException) e).messages).collect(Collectors.joining("\n")); }else { return e.getMessage(); } } /** * 日志对象 */ private static Logger log = LoggerFactory.getLogger(VciBaseUtil.class); /** * 生成PK值,uuid在高并发的时候会重复,但是非互联网产品中,同一个数据库表中的主键出现重复的概率较小 * 如果是互联网产品,需要将这个修改为redis中获取uuid * @return uuid的值 */ public static String getPk() { return UUID.randomUUID().toString(); } /** * 雪花ID * @return */ public static String getSnowflakePk() { return String.valueOf(getSnowflakePk(1,1)); } public static Long getSnowflakePk(long workerId,long dataCenterId){ Snowflake snowflake = IdUtil.getSnowflake(workerId,dataCenterId); return snowflake.nextId(); } /** * 字符串转数字 * @param string 字符串 * @return 数字 */ public static int getInt(String string) { int i = 0; if (string == null || "".equals(string.trim())) { return 0; } if(string.contains(".")){ string = string.substring(0,string.indexOf(".")); } try { i = Integer.parseInt(string); } catch (Exception e) { return 0; } return i; } /** * 把boolean型转化为数字 * @param b 布尔 * @return 数字 */ public static int getIntForBoolean(boolean b){ if (b) { return 1; } else { return 0; } } /** * 在hibernate中将结果转化为数字 * @param obj 结果的对象 * @return 数字 */ public static int getIntFromHibernateResult(Object obj){ if(obj == null){ return 0; } if(obj instanceof BigDecimal){ return ((BigDecimal)obj).intValue(); }else if(obj instanceof BigInteger){ return ((BigInteger)obj).intValue(); }else if(obj instanceof Double){ return ((Double)obj).intValue(); }else if(obj instanceof Long){ return ((Long)obj).intValue(); }else if(obj instanceof Short){ return ((Short)obj).intValue(); }else if(obj instanceof Float){ return ((Float)obj).intValue(); }else if(obj instanceof String){ try{ return Integer.valueOf(obj.toString()); }catch(Exception e){ return 0; } }else{ return 0; } } /** * 字符串转布尔型 * @param s 字符串 * @return true字符串返回boolean型的true,其余返回false */ public static boolean getBoolean(String s){ if(BooleanEnum.TRUE.getValue().equals(s)){ return true; }else{ return false; } } /** * 根据字符串获取对应的二进制 * @param s 字符 * @return 二进制对象 */ public static byte getByte(String s) { byte b = 0; if (s == null) { return 0; } try { b = Byte.parseByte(s); } catch (Exception e) { return 0; } return b; } /** * 字符转short * @param s 字符串 * @return short值 */ public static short getShort(String s) { short i = 0; if (s == null) { return 0; } try { i = Short.parseShort(s); } catch (Exception e) { return 0; } return i; } /** * 字符串转Long * @param s 字符串 * @return long */ public static long getLong(String s) { long l = 0; if (s == null) { return 0; } try { l = Long.parseLong(s); } catch (Exception e) { return 0; } return l; } /** * 字符串转浮点型 * @param s 字符串 * @return 浮点型 */ public static float getFloat(String s) { float f = 0; if (s == null) { return 0; } try { f = Float.parseFloat(s); } catch (Exception e) { return 0; } return f; } /** * 字符串转double型 * @param s 字符串 * @return double */ public static double getDouble(String s) { double d = 0; if (isNull(s)) { return 0; } try { d = Double.parseDouble(s); } catch (Exception e) { return 0; } return d; } /** * 去除最前面的逗号,去除后面的逗号 * @param s 字符串 * @return 去除末尾逗号 */ public static String removeComma(String s){ if(s == null || s.trim().length() == 0) { return s; } else{ if(s.startsWith(",")) { s = s.substring(1, s.length()); } if(s.endsWith(",")) { s = s.substring(0, s.length() - 1); } return s; } } /** * 为sql中使用in时,提供转换,注意in里的值不能超过1000 * @param s 字符串 * @return 返回sql语句 */ public static String toInSql(String s){ s= removeComma(s); if(s == null || s.trim().length() == 0) { return ""; } String[] temp = s.split(","); return toInSql(temp); } /** * 注意s的长度不能超过一千 * @param s 字符串 * @return insql */ public static String toInSql(String[] s){ if(s != null && s.length >0){ StringBuilder sb = new StringBuilder(); if(s!=null&&s.length>0){ for(int i = 0 ; i < s.length ; i ++){ if(s[i]!=null&&s[i].trim().length() >0 && !s[i].startsWith("'")) { sb.append("'") .append(s[i]) .append("',"); } } } return removeComma(sb.toString()); }else{ return ""; } } /** * 支持in 里数据为1000以上的 * @param field 字段名称 * @param s 原字符串 * @return 含in的SQL */ public static String toInSql(String field, String s){ if(StringUtils.isBlank(field) || StringUtils.isBlank(s)){ return ""; } return toInSql(field,removeComma(s).split(","),""); } /** * 支持in里数据1000以上 * @param field 字段名称 * @param s 原字符串 * @return 含in的SQL */ public static String toInSql(String field, String[] s){ return toInSql(field,s,"in"); } /** * 不等于 */ public static final String NOTIN="not in"; /** * 支持not in * @param field 字段 * @param s 字符串数组 * @param operation 操作方式 * @return insql */ public static String toInSql(String field, String[] s, String operation){ if(StringUtils.isBlank(field) || s == null || s.length == 0){ return ""; }else{ StringBuilder sb = new StringBuilder(); if(s!=null&&s.length>0){ String andOr = "or"; if(operation.trim().toLowerCase().equals(NOTIN)){ andOr = "and"; } for(int i = 0 ; i < s.length ; i ++){ if(s[i]!=null&&s[i].trim().length() >0 && !s[i].startsWith("'")) { if (i == 0) { sb.append(field).append(" ").append(operation).append(" ("); } if (i % 500 == 0 && i != 0) { sb.append(" ").append(andOr).append(" ").append(field).append(" ").append(operation).append(" ("); } sb.append("'").append(s[i]).append("'"); if (i % 500 != 499 && i != s.length - 1) { sb.append(","); } if (i % 500 == 499 || i == s.length - 1) { sb.append(") "); } } } } return sb.toString(); } } /** * 数组转为逗号分隔的字符串 使用array2String * @param array 数组 * @return 字符串 */ @Deprecated public static String arrayToString(String[] array){ if(array!= null && array.length>0){ StringBuilder sb = new StringBuilder(); for(int i = 0 ; i < array.length; i ++){ String record = array[i]; if(StringUtils.isNotBlank(record)) { sb.append(record) .append(","); } } return removeComma(sb.toString()); } return ""; } /** * 将集合转换为字符串 * @param collection 集合 * @return 字符串 */ public static String collectionToString(Collection collection){ if(!CollectionUtils.isEmpty(collection)){ StringBuilder sb = new StringBuilder(); Iterator it = collection.iterator(); while(it.hasNext()){ Object record = it.next(); if(record !=null && (!(record instanceof String) || StringUtils.isNotBlank(((String) record)))){ sb.append(record.toString()).append(","); } } return removeComma(sb.toString()); } return ""; } /** * 首字母大写 * @param s 字符串 * @return 含大写的字符串 */ public static String toUpForFirst(String s){ if(s== null || s.trim().length()==0) { return ""; } String temp = s.substring(0, 1); temp = temp.toUpperCase(); return temp + s.substring(1,s.length()); } /** * 首字母小写 * @param s 字符串 * @return 含大写的字符串 */ public static String toLowForFirst(String s){ if(s== null || s.trim().length()==0) { return ""; } String temp = s.substring(0, 1); temp = temp.toLowerCase(); return temp + s.substring(1,s.length()); } /** * 字符串中某个字符出现的次数 * @param s 字符串 * @param findC 要找的字符 * @return 截取后的字符串 */ public static int countOfString(String s, char findC) { Map charMap = new HashMap(); char[] cs = s.toCharArray(); for (char c : cs) { charMap.put(String.valueOf(c), (!charMap.containsKey(String.valueOf(c))? 1 : charMap.get(String.valueOf(c)) + 1)); } return charMap.get(String.valueOf(findC)); } /** * 带逗号的字符串转为list * @param s 字符串 * @return 字符串列表 */ public static List str2List(String s){ if (isNull(s)) { return null; } else { List l = new ArrayList(); Collections.addAll(l,removeComma(s).split(",")); return l; } } /** * 列表转为带逗号分隔的字符串 * @param ls 字符串列表 * @return 逗号分隔的字符串 */ public static String list2String(List ls){ if(ls == null || ls.size() == 0) { return ""; }else{ return ls.stream().collect(Collectors.joining(",")); } } /** * 判断字符串是不是空,不判断trim * @param o 字符串 * @return true表示空 */ public static boolean isNull(String o){ return StringUtils.isEmpty(o); } /** * 判断不是空,不判断trim * @param o 字符串 * @return true表示不为空 */ public static boolean isNotNull(String o){ return !isNull(o); } /** * 判断字符串是不是空,去除trim * @param o 字符串 * @return true表示为空,或者null,或"",或" " */ public static boolean isNullOrNullString(String o){ return StringUtils.isBlank(o); } /** * 字符串是否在数组中 * @param arr 数组对象 * @param s 字符串 * @return 不区分大小写 */ public static boolean inArray(String[] arr, String s) { if(arr!=null && s != null){ for(String a : arr){ if(s.trim().equalsIgnoreCase(a)) { return true; } } } return false; } /** * 是否在数组中 * @param arr 数组对象 * @param o 对象 * @return true表示在数组中 */ public static boolean inArray(Object[] arr, Object o){ if(arr!=null && o != null){ for(Object a : arr){ if(a.equals(o)){ return true; } } } return false; } /** * double取精度 * @param value 值 * @param scale 保留小数 * @param roundingMode 尾数处理方法 * @return 转换后的值 */ public static double round(double value, int scale, int roundingMode) { BigDecimal bd = new BigDecimal(value); bd = bd.setScale(scale, roundingMode); double d = bd.doubleValue(); bd = null; return d; } /** * 取精度,四舍五入法 * @param value 值 * @param scale 比例 * @return 转换后的值 */ public static double round(double value,int scale){ return round(value,scale, BigDecimal.ROUND_HALF_UP); } /** * 判断邮件地址是否合法 * @param string 字符串 * @return true表示为邮件地址 */ public static boolean isEmail(String string) { if (StringUtils.isBlank(string)) { return false; } String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; Pattern p; Matcher m; p = Pattern.compile(regEx1); m = p.matcher(string); if (m.matches()) { return true; }else { return false; } } /** * 判断是否为数字 * @param s 字符串 * @return true表示符合 */ public static boolean isNumber(String s){ if(StringUtils.isNotBlank(s) && s.matches("\\d+\\.?\\d*")){ return true; }else{ return false; } } /** * 获取属性列表中得某个属性 * @param fieldName 字段名称 * @param fieldsList 字段的对象列表 * @return 符合条件的属性对象 */ public static Field getFieldForObject(String fieldName, List fieldsList){ if(StringUtils.isBlank(fieldName)){ return null ; } if(fieldsList != null && fieldsList.size() > 0){ for(Field field : fieldsList){ if(field.getName().toLowerCase().equals(fieldName.toLowerCase())){ return field; } } } return null ; } /** * 获取字段的setter * @param c 类对象 * @param fieldName 字段名称 * @return 符合条件的对象 */ public static Method getSetmethod(Class c, String fieldName){ if(c!=null&&StringUtils.isNotBlank(fieldName)){ try { PropertyDescriptor pd = new PropertyDescriptor(fieldName, c); return pd.getWriteMethod(); } catch (SecurityException e) { if(log.isErrorEnabled()){ log.error("获取getter出错",e); } } catch (IntrospectionException e) { if(log.isErrorEnabled()){ log.error("获取getter出错",e); } } } return null; } /** * 获取字段的getter * @param c 类对象 * @param fieldName 属性名称 * @return 符合条件的对象 */ public static Method getGetmethod(Class c, String fieldName){ if(c!=null&&StringUtils.isNotBlank(fieldName)){ try { PropertyDescriptor pd = new PropertyDescriptor(fieldName, c); return pd.getReadMethod(); } catch (SecurityException e) { if(log.isErrorEnabled()){ log.error("获取getter出错",e); } } catch (IntrospectionException e) { if(log.isErrorEnabled()){ log.error("获取getter出错",e); } } } return null; } /** * 获取Column注解上的name的值 * @param fieldAnnotaions 所有的注解对象 * @return name的值 */ public static String getColumnAnnotaionNameValue(Annotation[] fieldAnnotaions){ return getAnnotationValue("com.vci.starter.web.annotation.Column,javax.persistence.Column","name",fieldAnnotaions); } /** * 获取注解中的某个方法的值 * @param annotationName 注解的名称 * @param methodName 方法名称 * @param fieldAnnotaions 注解的集合 * @return 符合条件的值 */ public static String getAnnotationValue(String annotationName,String methodName,Annotation[] fieldAnnotaions){ String[] annotaionNameArray = annotationName.split(","); for(Annotation annotation : fieldAnnotaions){ String anname = annotation.annotationType().getName(); if(inArray(annotaionNameArray,anname)){ String name = null; try { name = (String)annotation.getClass().getMethod(methodName).invoke(annotation); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return name; } } return null; } /** * 从对象上获取cbo里的值 * @param field 字段对象 * @param c 类对象 * @return cbo中的值 */ public static String getCboAttrNameFromField(Field field, Class c){ String clientBoAttrName = field.getName().toLowerCase(); String name = null; if(!VciQueryWrapperForDO.USER_TABLE_COMPATIBILITY &&( VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(clientBoAttrName) ||VciQueryWrapperForDO.REVISION_MANAGE_FIELD_MAP.containsKey(clientBoAttrName) ||VciQueryWrapperForDO.LIFECYCLE_MANAGE_FIELD_MAP.containsKey(clientBoAttrName) ||VciQueryWrapperForDO.LINK_TYPE_FIELD_MAP.containsKey(clientBoAttrName))){ //是新平台,不用column注解上去获取名字 }else { name = getColumnAnnotaionNameValue(field.getDeclaredAnnotations()); if (StringUtils.isBlank(name)) { //找一下Get方法上..set方法上肯定是不支持的, Method getMethod = getGetmethod(c, field.getName()); if (getMethod != null) { name = getColumnAnnotaionNameValue(getMethod.getDeclaredAnnotations()); } if (StringUtils.isBlank(name)) { //参照或者是枚举的 name = getAnnotationValue("com.vci.starter.web.annotation.Transient", "referColumn", field.getDeclaredAnnotations()); } } } if(StringUtils.isNotBlank(name)){ clientBoAttrName = name; } return clientBoAttrName; } /** * 是否为基础类型 * @param c 类对象 * @return true表示基础类型 */ public static boolean isBasicType(Class c){ if(c == null){ return false; } if(c.isArray()){ return isBasicType(c.getComponentType()); } return ClassUtil.isPrimitive(c); } /** * 获取类中的字段映射 * @param c 类对象 * @return key为业务类型中的字段名称,value为类中的属性名称 */ public static Map getFieldNameMap(Class c){ Map fieldMap = new HashMap(); List allField = getAllFieldForObj(c); if(allField!=null&&allField.size()>0){ for(Field field : allField){ if(!field.getName().equals("serialVersionUID")){ Class fieldTypeClass = field.getType(); if(isBasicType(fieldTypeClass)){ String referColumn = getAnnotationValue("com.vci.starter.web.annotation.Transient","referColumn",field.getDeclaredAnnotations()); if (StringUtils.isNotBlank(referColumn)){ //说明不是持久化的属性,但是从平台中查询出来后可能得需要显示 fieldMap.put(referColumn, field.getName()); }else{ String clientBoAttrName = getCboAttrNameFromField(field,c); fieldMap.put(clientBoAttrName, field.getName()); } }else{ //不是基本类型的,那一定不是要的属性 } } } } return fieldMap; } /** * 从对象上获取属性的值 * @param fieldName 属性名 * @param sourceObject 对象 * @return 属性的值 */ public static Object getValueFromField(String fieldName, Object sourceObject){ if(StringUtils.isNotBlank(fieldName)){ try { Method getMethod = getGetmethod(sourceObject.getClass(), fieldName); if(getMethod !=null){ return getMethod.invoke(sourceObject); }else{ //说明没有设置getter,比如BO和LO对象这种 Field field = getFieldForObject(fieldName, sourceObject); if(field !=null){ field.setAccessible(true); return field.get(sourceObject); } } } catch (SecurityException e) { if(log.isErrorEnabled()){ log.error("从属性上获取值",e); } } catch (IllegalAccessException e) { if(log.isErrorEnabled()){ log.error("从属性上获取值",e); } } catch (IllegalArgumentException e) { if(log.isErrorEnabled()){ log.error("从属性上获取值",e); } } catch (InvocationTargetException e) { if(log.isErrorEnabled()){ log.error("从属性上获取值",e); } } } return null; } /** * 将属性值赋值到对象上 * @param fieldName 属性名 * @param obj 对象 * @param value 属性值 */ public static void setValueForField(String fieldName, Object obj, String value){ try{ Field field = getFieldForObject(fieldName,obj); if(field!=null){ setValueForField(field,obj,value); } }catch (Exception e) { if(log.isErrorEnabled()) { log.error("设置属性的值出错了错误",e); } } } /** * 将属性值赋值到对象上 * @param field 属性对象 * @param obj 对象 * @param value 属性值 */ public static void setValueForField(Field field,Object obj, String value){ try { if (field != null && StringUtils.isNotBlank(value)) { field.setAccessible(true); Method setMethod = getSetmethod(field.getDeclaringClass(), field.getName()); Class type = field.getType(); //从平台读取到的值不会为null,为空时为"";所以不处理空值 Object valueObj = null; if (type.equals(int.class) || type.equals(Integer.class)) { valueObj = VciBaseUtil.getInt(value); } else if (type.equals(float.class) || type.equals(Float.class)) { valueObj = VciBaseUtil.getFloat(value); } else if (type.equals(long.class) || type.equals(Long.class)) { valueObj = VciBaseUtil.getLong(value); } else if (type.equals(Double.class) || type.equals(double.class)) { valueObj = VciBaseUtil.getDouble(value); //从平台中查询出来就不用处理精度了,因为平台会自行处理 } else if (type.equals(Date.class)) { DateConverter dateConverter = new DateConverter(); dateConverter.setAsText(value); valueObj = dateConverter.getValue(); } else if (type.equals(String.class)) { valueObj = value; } else { valueObj = value; if (log.isErrorEnabled()) { log.error("不支持的类型" + type.toString()); } } if (setMethod != null) { setMethod.invoke(obj, valueObj); } else { field.set(obj, valueObj); } } }catch (Throwable e){ if(log.isErrorEnabled()) { log.error("设置属性的值出错了错误",e); } } } /** * 调用属性的setter赋值 * @param field 属性对象 * @param obj 要赋值的对象 * @param value 值 */ public static void setValueForMethod(Field field, Object obj , Object value){ try { if (field != null) { field.setAccessible(true); Method setMethod = getSetmethod(field.getDeclaringClass(), field.getName()); setMethod.invoke(obj, value); } }catch (Exception e){ log.error("反射调用方法出现了错误,",e); } } /** * 把object对象转化为字符串 * @param obj 对象 * @return 字符串 */ public static String getStringValueFromObject(Object obj){ if(obj == null){ return ""; }else{ if(obj instanceof Integer || obj instanceof Float || obj instanceof Long || obj instanceof Double){ if(obj instanceof Double){ Double aDouble = (Double) obj; if(aDouble!=null&& aDouble%1==0){ return String.valueOf(aDouble.intValue()); } } return String.valueOf(obj); }else if(obj instanceof Date){ return VciDateUtil.date2Str((Date)obj, VciDateUtil.DateTimeMillFormat); }else{ return obj.toString(); } } } /** * 提示参数为空 * @param s 相关的参数,两两组合,第一个为参数的对象,第二个为显示的名称 * @throws VciBaseException 如果参数为空的时候会抛出异常 */ public static void alertNotNull(Object... s) throws VciBaseException { if(s!=null && s.length>0){ for(int i = 0 ; i < s.length ; i ++){ Object obj = s[i]; String param = ""; try{ i++; param = s[i].toString(); }catch(Exception e){ } if(obj==null){ throw new VciBaseException("参数[{0}]不能为空",new String[]{param}); }else { if(obj instanceof Collection){ if(CollectionUtils.isEmpty((Collection)obj)){ throw new VciBaseException("参数[{0}]不能为空",new String[]{param}); } }else{ if(StringUtils.isBlank(obj.toString())){ throw new VciBaseException("参数[{0}]不能为空",new String[]{param}); } } } } } } /** * 提示集合里的参数为空,(2020-09被废弃,请直接使用alertNotNull方法) * @param param 提示信息 * @param collections 集合 * @throws VciBaseException 参数为空的时候会抛出异常 */ @Deprecated public static void alertCollectionNotNull(String param, Collection collections) throws VciBaseException{ if(CollectionUtils.isEmpty(collections)){ throw new VciBaseException("参数{0}不能为空",new String[]{param}); } } /** * oracle in 查询不能超过1000,转换一下集合 * 由于SQL语句1000个可能很长,超过oracle10g,所以牺牲性能分配为500个数组 * @param list 需要转换的列表内容 * @return 分组后的list */ public static List> switchListForOracleIn(List list) { List> listHasList = new ArrayList>(); if(list == null){ return listHasList; } List newList = new ArrayList(); for(Object obj : list){ //为了让list还可以添加内容,因为使用sublist后,list不能再Add了 newList.add((T)obj); } int muti = 1; if(newList.size() >500){ int balance = newList.size()%500; muti = (newList.size() - balance)/500 + (balance == 0?0:1); } for(int i = 0 ; i < muti; i ++){ int start = i*500; int end = start + 500; if(i == muti-1 || end >newList.size() ){ end = newList.size(); } List subList = newList.subList(start,end); listHasList.add(subList); } return listHasList; } /** * oracle in 查询不能超过1000,转换一下集合 * 由于SQL语句1000个可能很长,超过oracle10g,所以牺牲性能分配为500个数组 * @param list 需要转换的列表内容 * @return 分组后的list */ public static Collection> switchCollectionForOracleIn(Collection list) { return switchCollectionForOracleIn(list,500); } /** * 转换集合的大小,这个用在feign调用的时候,不要在sql查询的时候使用 * @param collection 需要转换的列表内容 * @param preSize 每个分组的大小 * @return 分组后的list */ public static Collection> switchCollectionForOracleIn(Collection collection,int preSize) { Collection> listHasList = new ArrayList<>(); if(collection == null){ return listHasList; } List newList = new ArrayList(); for(Object obj : collection){ //为了让list还可以添加内容,因为使用sublist后,list不能再Add了 newList.add((T)obj); } int muti = 1; if(newList.size() >preSize){ int balance = newList.size()%preSize; muti = (newList.size() - balance)/preSize + (balance == 0?0:1); } for(int i = 0 ; i < muti; i ++){ int start = i*preSize; int end = start + preSize; if(i == muti-1 || end >newList.size() ){ end = newList.size(); } List subList = newList.subList(start,end); listHasList.add(subList); } return listHasList; } /** * oracle in 查询不能超过1000,转换一下集合。注意这个顺序可能会发生变化 * 由于SQL语句1000个可能很长,超过oracle10g,所以牺牲性能分配为500个数组 * @param set set集合 * @return 转换后的set * @throws VciBaseException */ public static Set> switchSetForOracleIn(Set set){ Set> listHasList = new HashSet>(); if(set == null){ return listHasList; } int muti = 1; if(set.size() >500){ int balance = set.size()%500; muti = (set.size() - balance)/500 + (balance == 0?0:1); } List list = new ArrayList(); //为了保证以前的引用关系,不是有转数组的方法 Iterator it = set.iterator(); while(it.hasNext()){ list.add(it.next()); } for(int i = 0 ; i < muti; i ++){ int start = i*500; int end = start + 500; if(i == muti-1 || end >set.size() ){ end = set.size(); } List subList = list.subList(start,end); Set subSet = new HashSet(); for(Object obj : subList){ subSet.add(obj); } listHasList.add(subSet); } return listHasList; } /** * oracle in 查询不能超过1000,转换一下集合,注意这个顺序可能会发生变化 * 由于SQL语句1000个可能很长,超过oracle10g,所以牺牲性能分配为500个数组 * @param vector vector集合 * @return 转换后的迭代器 * @throws VciBaseException */ public static Vector> switchVectorForOracleIn(Vector vector) { Vector> listHasList = new Vector>(); if(vector == null){ return listHasList; } int muti = 1; if(vector.size() >500){ int balance = vector.size()%500; muti = (vector.size() - balance)/500 + (balance == 0?0:1); } List list = new ArrayList(); //为了保证以前的引用关系,不是有转数组的方法 Iterator it = vector.iterator(); while(it.hasNext()){ list.add(it.next()); } for(int i = 0 ; i < muti; i ++){ int start = i*500; int end = start + 500; if(i == muti-1 || end >vector.size() ){ end = vector.size(); } List subList = list.subList(start,end); Vector subSet = new Vector(); for(Object obj : subList){ subSet.add(obj); } listHasList.add(subSet); } return listHasList; } /** * 获取当前用户的用户名 * @return 当前用户的用户名 */ public static String getCurrentUserId( ){ SessionInfo s = getCurrentUserSessionInfoNotException(); if(s !=null){ return s.getUserId(); }else{ return ""; } } /** * 获取当前用户的主键 * @return 当前用户的主键 */ public static String getCurrentUserOid(){ SessionInfo s = getCurrentUserSessionInfoNotException(); if(s !=null){ return s.getUserOid(); }else{ return ""; } } /** * json字符串转为对象 * @param jsonString json字符串 * @param beanClass 对象类型 * @return java对象 */ public static T jsonString2JavaBean(String jsonString, Class beanClass){ return (T) JSONObject.parseObject(jsonString, beanClass); } /** * 判断字符串是否为空,为空则添加默认值 * @param str 字符串 * @param defaultValue 默认值 */ public static void ifNullSetDefautl(String str, String defaultValue) { if(isNull(str)) { str = defaultValue; } } /** * 从json字符串中获取第一个对象 * @param jsonString json字符串 * @param beanClass 对象类型 * @return java对象 * @throws Exception */ public static T getFristObjectFromJson(String jsonString, Class beanClass){ if(!isNull(jsonString)) { return JSONObject.parseArray(jsonString, beanClass).get(0); }else { return null; } } /** * 获取当前线程中的用户对象 * @return 会话信息 * @throws VciBaseException 如果没有登录会抛出异常 */ public static SessionInfo getCurrentUserSessionInfo() throws VciBaseException { SessionInfo si= getCurrentUserSessionInfoNotException(); if(si==null){ throw new VciBaseException("noLogin",new String[]{"没有当前用户信息"}); } return si; } /** * 获取当前线程中的用户对象 * @return 会话对象 */ public static SessionInfo getCurrentUserSessionInfoNotException() { return WebThreadLocalUtil.getCurrentUserSessionInfoInThread(); } /** * 设置当前线程中的用户对象 * @param sessionInfo 用户对象 */ public static void setCurrentUserSessionInfo(SessionInfo sessionInfo){ WebThreadLocalUtil.setCurrentUserSessionInfoInThread(sessionInfo); } /** * 是否查询总数 * @return true表示查询 */ public static boolean isQueryTotal(){ String needQueryTotal = WebThreadLocalUtil.getNeedQueryTotalInThread(); if("false".equalsIgnoreCase(needQueryTotal)){ return false; }else{ return true; } } /** * 将对象转换为字符串出来 * @return json字符串 */ public static String getJSONStringWithDateFormat(Object obj){ return JSONObject.toJSONStringWithDateFormat(obj, VciDateUtil.DateTimeMillFormat, SerializerFeature.WriteDateUseDateFormat); } /** * 对象转换为map * @param o 对象 * @return map对象 */ public static Map objectToMap(Object o) { Map map = new HashMap(); if(o!=null) { String jsonString = JSONObject.toJSONStringWithDateFormat(o, VciDateUtil.DateTimeMillFormat, SerializerFeature.WriteDateUseDateFormat); if(org.apache.commons.lang3.StringUtils.isNotBlank(jsonString)) { JSONObject jsonObject = JSONObject.parseObject(jsonString); if(jsonObject!=null){ for(String key : jsonObject.keySet()){ map.put(key,jsonObject.get(key)); } } } } return map; } /** * 对象转换为map,值为字符串 * @param o 对象 * @return map对象 */ public static Map objectToMapString(Object o){ Map map = new HashMap(); if(o!=null) { String jsonString = JSONObject.toJSONStringWithDateFormat(o, VciDateUtil.DateTimeMillFormat, SerializerFeature.WriteDateUseDateFormat); if(org.apache.commons.lang3.StringUtils.isNotBlank(jsonString)) { JSONObject jsonObject = JSONObject.parseObject(jsonString); if(jsonObject!=null){ for(String key : jsonObject.keySet()){ map.put(key,jsonObject.getString(key)); } } } } return map; } /** * 属性值是否为空 * @param obj 对象 * @param f 属性对象 * @return true不是空 */ public static boolean isNotNullForField(Object obj, Field f){ if(!"serialVersionUID".equalsIgnoreCase(f.getName()) &&!"DEFAULT_INITIAL_CAPACITY".equalsIgnoreCase(f.getName())&&null!=obj && !isNullOrNullString(obj.toString())) { return true; } else { return false; } } /** * 数组转换为String * @param array 数组对象 * @return 逗号链接的字符串 */ public static String array2String(String[] array) { if(null == array || array.length == 0) { return ""; } else{ String ss = ""; for(String s : array){ ss += s + ","; //1.8可以 } return removeComma(ss); } } /** * 对象转换为字符串 * @param obj 对象 * @return 字符串 */ public static String getString(Object obj){ if(obj == null) { return ""; } if(obj instanceof Date) { return VciDateUtil.date2Str((Date) obj, VciDateUtil.DateTimeFormat); } return String.valueOf(obj); } /** * 拷贝值到map * @param source 原对象 * @param target 目标对象 * @param copyField 要拷贝的属性值 */ public static void copyValueForMap(Map source, Map target, String[] copyField){ Map copyFieldMap = new HashMap(); for(String field : copyField) { copyFieldMap.put(field, field); } copyValueForMap(source,target,copyFieldMap); } /** * 为map拷贝值 * @param source 源对象 * @param target 目标对象 * @param copyField key为目标对象里的字段, */ public static void copyValueForMap(Map source, Map target, Map copyField){ try{ Iterator it = copyField.keySet().iterator(); while(it.hasNext()){ String field = it.next(); target.put(field, source.get(copyField.get(field))); } }catch(Exception e){ } } /** * 从映射对象中获取double的值 * @param field 字段名称 * @param record 映射对象 * @return double类型的值,不存在时返回null */ public static Double getDoubleFromMap(String field, Map record) { if(isNullOrNullString(field) || record == null || !record.containsKey(field)) { return null; }else{ Object v = record.get(field); if(v instanceof BigDecimal){ return ((BigDecimal)v).doubleValue(); }else if(v instanceof Double){ return ((Double)v).doubleValue(); } else{ return getDouble((String)v); } } } /** * 从映射对象中获取某个key的字符串类型值 * @param key 键 * @param data 映射对象 * @return string类型的值,不存在时返回"" */ public static String getDataByKey(String key, Map data){ String value = ""; if(data.containsKey(key)) { value = (String) data.get(key); } if(value == null) { value = ""; } return value; } /** * 获取不是空值的映射,且key是小写 * @param map 获取不包含空值的映射对象 * @return 不包含空值的映射对象 */ public static Map getNotNullMap(Map map){ if(map == null){ return new HashMap(); } Iterator it = map.keySet().iterator(); Map unNullMap = new HashMap(); while(it.hasNext()){ Object key = it.next(); String newKey = key.toString().toLowerCase(); Object value = map.get(key); if(value !=null){ if(value instanceof String && isNotNull(value.toString())){ unNullMap.put(newKey, value); }else if(!(value instanceof String)){ unNullMap.put(newKey, value); } } } return unNullMap; } /** * 获取对象中的所有属性,包括其继承的属性 * @param c 对象所属的类 * @return 所有的字段 */ public static List getAllFieldForObj(Class c){ List allField = new ArrayList(); Set fieldNameSet = new HashSet<>(); for(Class classz = c; classz != Object.class ; classz = classz.getSuperclass() ){ Field[] thisClassField = classz.getDeclaredFields(); for(Field field : thisClassField){ if(!field.getName().equals("serialVersionUID")){ String fieldLowerName = field.getName().toLowerCase(); if(!fieldNameSet.contains(fieldLowerName)){ fieldNameSet.add(fieldLowerName); allField.add(field); } } } } return allField; } /** * 获取对象的主键 * @param c 对象所属的类 * @return 属性对象 */ public static Field getPkFieldForObj(Class c){ List allField = getAllFieldForObj(c); if(allField!=null&&allField.size()>0){ for(Field field : allField){ if(field.isAnnotationPresent(Id.class)){ return field; } } //如果没找到,那就找oid for(Field field : allField){ if(field.getName().toLowerCase().equalsIgnoreCase("oid")){ return field; } } } return null; } /** * 获取ts的字段 * @param c 对象所属的类 * @return 时间戳的属性对象 */ public static Field getTsField(Class c){ List allField = getAllFieldForObj(c); if(allField!=null&&allField.size()>0){ for(Field field : allField){ if(field.getName().equals("ts")){ return field; } } } return null; } /** * 根据名称获取字段 * @param fieldName 属性的名称 * @param obj 数据对象 * @return 属性对象 */ public static Field getFieldForObject(String fieldName, Object obj){ if(obj == null){ return null; } return getFieldForObject(fieldName,obj.getClass()); } /** * 根据属性名称获取属性的对象 * @param fieldName 属性名称 * @param c 对象所属类 * @return 属性对象 */ public static Field getFieldForObject (String fieldName, Class c){ List allField = getAllFieldForObj(c); if(allField!=null&&allField.size()>0){ for(Field field : allField){ if(field.getName().toLowerCase().equalsIgnoreCase(fieldName.toLowerCase())){ return field; } } } return null; } /** * 获取字段的setter * @param c 对象所属类 * @param field 属性对象 * @return set的方法 */ public static Method getSetmethod(Class c, Field field){ return getSetmethod(c,field.getName()); } /** * 获取字段的getter * @param c 对象所属类 * @param field 属性对象 * @return get方法 */ public static Method getGetmethod(Class c, Field field){ return getGetmethod(c,field.getName()); } /** * 根据方法的名字获取方法的对象 * @param classObj 所属的类 * @param methodName 方法的名称 * @return 方法的对象 */ public static Method getMethodByName(Class classObj,String methodName){ VciBaseUtil.alertNotNull(classObj,"获取方法的对象所属的类",methodName,"方法的名字"); Method[] methods = classObj.getMethods(); List sameMethods = Arrays.stream(methods).filter(method -> method.getName().equalsIgnoreCase(methodName)).collect(Collectors.toList()); if(!CollectionUtils.isEmpty(sameMethods)){ return sameMethods.get(0); }else{ return null; } } /** * 将whereSql里的内容转化到查询map里 * @param whereSql 查询语句sql * @return map对象,key是查询条件,value是条件值 */ public static Map whereSql2Map( String whereSql) { Map map = new HashMap(); if(isNotNull(whereSql)){ String[] selects = whereSql.split("and"); if(selects!=null&&selects.length>0){ for(String s : selects){ s = s.trim(); map.put(s.substring(0,s.indexOf(" ")).trim(), s.substring(s.indexOf(" ") +1).trim()); } } } return map; } /** * 获取随机的文件名称 * @param prefix 前缀 * @return 文件名称 */ public synchronized static String getRoundFilename(String prefix) { if(prefix == null) { prefix = ""; } return prefix + System.currentTimeMillis(); } private static String localIp = null; /** * 获取本机地址,不是客户端电脑的ip,是当前服务所在的ip * @return 本机地址,如果没有则未127.0.0.1 */ public static String getLocalIp(){ if(localIp == null){ try { InetAddress inetAddress = getLocalHostLANAddress(); if (inetAddress == null) { localIp = "127.0.0.1"; } else { localIp = inetAddress.getHostAddress(); } }catch (Exception e){ localIp = "127.0.0.1"; } } return localIp; } /** * 从网络接口上获取ip地址 * @return IP接口对象 * @throws Exception 查询出错时会抛出异常 */ private static InetAddress getLocalHostLANAddress() throws Exception { try { InetAddress candidateAddress = null; // 遍历所有的网络接口 for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) { NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); // 在所有的接口下再遍历IP for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) { InetAddress inetAddr = (InetAddress) inetAddrs.nextElement(); if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址 if (inetAddr.isSiteLocalAddress()) { // 如果是site-local地址,就是它了 return inetAddr; } else if (candidateAddress == null) { // site-local类型的地址未被发现,先记录候选地址 candidateAddress = inetAddr; } } } } if (candidateAddress != null) { return candidateAddress; } // 如果没有发现 non-loopback地址.只能用最次选的方案 InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); return jdkSuppliedAddress; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 获取当前用户的密级 * @return 如果用户没有登录,返回非密 */ public static Integer getCurrentUserSecret() { SessionInfo currentUserSession = getCurrentUserSessionInfoNotException(); if(currentUserSession != null){ return getInt(currentUserSession.getUserSecret()); }else{ return UserSecretEnum.NONE.getValue(); } } /** * 获取项目运行时的路径,在开发环境里的地址是到target文件夹 * @return 项目运行的环境地址,开发环境为target所在的地址 */ public static String getProjectPath(){ String path = ""; try { String jarFilePath = ResourceUtils.getURL("classpath:").getPath(); if(jarFilePath.contains("!")){ path = new File(jarFilePath).getParentFile().getParentFile().getParent(); }else { path = new File(jarFilePath).getParent(); } }catch (IOException e){ throw new VciBaseException("获取当前服务所在的文件夹出现了错误"); } if(path.startsWith("file:\\")){ path = path.substring(6); } return path; } /** * 从数据对象上获取业务类型的名称 * @param modelClass 数据对象所属的类 * @return 如果存在注解就获取注解上的名称,否则获取类的名称 */ public static String getBtmTypeNameFromDO(Class modelClass){ if(modelClass.isAnnotationPresent(VciBtmType.class)){ VciBtmType btmType = modelClass.getDeclaredAnnotation(VciBtmType.class); if(btmType != null){ return btmType.name(); } } String name = modelClass.getSimpleName(); if(name.endsWith("DO")){ name = name.substring(0,name.length()-2); } return name; } /** * 从数据对象上获取链接类型的名称 * @param modelClass 数据对象所属的类 * @return 如果存在注解就获取注解上的名称,否则获取类的名称 */ public static String getLinkTypeNameFromDO(Class modelClass){ if(modelClass.isAnnotationPresent(VciLinkType.class)){ VciLinkType linkType = modelClass.getDeclaredAnnotation(VciLinkType.class); if(linkType !=null){ return linkType.name(); } } String name = modelClass.getSimpleName(); if(name.endsWith("DO")){ name = name.substring(0,name.length()-2); } return name; } /** * 根据业务类型获取表格名称 * @param btmname 业务类型,并且不能是视图 * @return 数据库表格名称 */ public static String getTableName(String btmname) { return (VciQueryWrapperForDO.USER_TABLE_COMPATIBILITY?"platformbtm_":"vcibt_") + btmname.trim().toLowerCase(); } /** * 根据链接类型获取表格名称 * @param linkName 链接类型 * @return 数据库表格名称 */ public static String getLinkTableName(String linkName){ return (VciQueryWrapperForDO.USER_TABLE_COMPATIBILITY?"platformlt_":"vcilt_")+ linkName.trim().toLowerCase(); } /** * 是否不是系统隐藏属性 * @param fieldName 属性的名称 * @return true表示不是隐藏 */ public static boolean isNotHiddenField(String fieldName){ if("id".equalsIgnoreCase(fieldName) || "name".equalsIgnoreCase(fieldName) || "description".equalsIgnoreCase(fieldName)){ return true; } if(VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(fieldName.toLowerCase())){ return false; } if(VciQueryWrapperForDO.REVISION_MANAGE_FIELD_MAP.containsKey(fieldName.toLowerCase())){ return false; } return true; } /** * 利用反射将map集合封装成bean对象 * @param map map集合 * @param clazz map集合所映射的bean对象 * @return 映射对象 */ public static T mapToBean(Map map, Class clazz) throws Exception { if(!CollectionUtils.isEmpty(map)){ Map dataMap = new ConcurrentHashMap<>(); List allFieldForObj = getAllFieldForObj(clazz); allFieldForObj.parallelStream().forEach(field->{ String key = map.keySet().stream().filter(s -> s.equalsIgnoreCase(field.getName())).findFirst().orElseGet(() -> null); if(StringUtils.isNotBlank(key)){ dataMap.put(field.getName(),map.get(key)); } }); return BeanUtil.toBeanIgnoreCase(dataMap, clazz, true); } return null; } /** * 使用freemarker替换值 * @param freemarker 表达式 * @param replaceMap 使用替换的数据源 * @return 替换后的值 */ public static String replaceByFreeMarker(String freemarker,Map replaceMap){ if(StringUtils.isBlank(freemarker)){ return ""; } freemarker = freemarker.replace("root.${","${").replace("sourceData.${","${"); //先配置 Configuration configuration = new Configuration(Configuration.VERSION_2_3_23); StringTemplateLoader templateLoader = new StringTemplateLoader(); configuration.setTemplateLoader(templateLoader); configuration.setDefaultEncoding("UTF-8"); try { Template template = new Template("temp",freemarker,configuration); StringWriter stringWriter = new StringWriter(); template.process(replaceMap, stringWriter); return stringWriter.toString(); } catch (IOException | TemplateException e) { throw new VciBaseException(e.getLocalizedMessage(),new String[0],e); } } /** * url的内容转换为参数 * @param url 路径 * @return 参数的格式 */ public static Map getParamsByUrl(String url){ if(StringUtils.isBlank(url)){ return new HashMap<>(); } String[] array = url.split("&"); Map params = new HashMap<>(); for(String temp : array){ if(temp.contains("=")){ String[] keyValues = temp.split("="); params.put(keyValues[0],keyValues[1]); }else{ params.put(temp,""); } } return params; } /** * 字符是否为中文 * Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS : 4E00-9FBF:CJK 统一表意符号 Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS :F900-FAFF:CJK 兼容象形文字 Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A :3400-4DBF:CJK 统一表意符号扩展 A Character.UnicodeBlock.GENERAL_PUNCTUATION :2000-206F:常用标点 Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION :3000-303F:CJK 符号和标点 Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS :FF00-FFEF:半角及全角形式 * @param c 字符 * @return true 是中文 * */ public static boolean isChinese(char c){ Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if(ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS ||ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS ||ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||ub == Character.UnicodeBlock.GENERAL_PUNCTUATION // GENERAL_PUNCTUATION 判断中文的“号 ||ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION // CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号 ||ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS // HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的,号 ) { return true; } return false; } /** * map不区分大小写判断 * @param map 数据 * @param key key * @return true表示存在 */ public static boolean containsKeyUnCaseForMap(Map map,String key){ if(!CollectionUtils.isEmpty(map)){ final boolean[] finded = {false}; map.forEach((k,value)->{ if(k instanceof String && k.toString().toLowerCase(Locale.ROOT).equalsIgnoreCase(key)){ finded[0] = true; return; } }); return finded[0]; } return false; } /** * 是否为中文 * @param str 字符串 * @return true表示有中文 */ public static boolean isChinese(String str){ char[] ch = str.toCharArray(); for (char c : ch) { if(isChinese(c)) { return true; } } return false; } /** * 全角转半角 * @param input 转换前 * @return 转换后 */ public static String toDBC(String input){ if(StringUtils.isBlank(input)){ return input; } char[] c = input.toCharArray(); for (int i = 0; i < c.length; i++) { if(c[i] == '\u3000'){ c[i] = ' '; }else if(c[i] > '\uFF00' && c[i] < '\uFF5F'){ c[i] = (char) (c[i]-65248); } } return new String(c); } /** * 半角转全角 * @param input 转换前 * @return 转换后 */ public static String toSBC(String input){ if(StringUtils.isBlank(input)){ return input; } char[] c = input.toCharArray(); for (int i = 0; i < c.length; i++) { if(c[i] == '\u3000'){ c[i] = ' '; }else if(c[i] > '\uFF00' && c[i] < '\uFF5F'){ c[i] = (char) (c[i] + 65248); } } return new String(c); } /** * 将string集合转为stirng数组 * @param strCollection string集合 * @return string数组 */ public static String[] collection2StrArr(Collection strCollection){ String[] strArr = new String[strCollection.size()]; strCollection.toArray(strArr); return strArr; } }