2022-03-21 20:09:10 +08:00
|
|
|
|
package com.engine.salary.util.valid;
|
|
|
|
|
|
|
2024-05-06 16:03:29 +08:00
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
2022-03-21 20:09:10 +08:00
|
|
|
|
import com.engine.salary.exception.SalaryRunTimeException;
|
|
|
|
|
|
import com.engine.salary.util.SalaryI18nUtil;
|
2024-05-06 16:03:29 +08:00
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
2022-03-21 20:09:10 +08:00
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
2024-05-06 16:03:29 +08:00
|
|
|
|
import weaver.general.Util;
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
|
|
|
|
|
import java.beans.BeanInfo;
|
|
|
|
|
|
import java.beans.Introspector;
|
|
|
|
|
|
import java.beans.PropertyDescriptor;
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
|
import java.text.SimpleDateFormat;
|
2022-03-22 10:42:26 +08:00
|
|
|
|
import java.util.*;
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 参数校验
|
|
|
|
|
|
* <p>Copyright: Copyright (c) 2022</p>
|
|
|
|
|
|
* <p>Company: 泛微软件</p>
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author qiantao
|
|
|
|
|
|
* @version 1.0
|
|
|
|
|
|
**/
|
2024-05-06 16:03:29 +08:00
|
|
|
|
@Slf4j
|
2022-03-21 20:09:10 +08:00
|
|
|
|
public class ValidUtil {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 通过反射来获取javaBean上的注解信息,判断属性值信息,然后通过注解元数据
|
|
|
|
|
|
* 来返回
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param t
|
|
|
|
|
|
*/
|
2022-03-22 10:42:26 +08:00
|
|
|
|
public static <T> void doValidator(T t, RuntimeTypeEnum... runtime) {
|
2022-03-21 20:09:10 +08:00
|
|
|
|
Class<?> clazz = t.getClass();
|
|
|
|
|
|
Field[] fields = clazz.getDeclaredFields();
|
|
|
|
|
|
for (Field field : fields) {
|
|
|
|
|
|
DataCheck rule = field.getDeclaredAnnotation(DataCheck.class);
|
|
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
if (null == rule) {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
boolean needValid = false;
|
|
|
|
|
|
RuntimeTypeEnum[] runtimeTypeEnums = rule.runtime();
|
|
|
|
|
|
if (Arrays.stream(runtimeTypeEnums).anyMatch(r -> r == RuntimeTypeEnum.AUTO)) {
|
|
|
|
|
|
needValid = true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
//传了运行类型,校验字段上运行类型和传入的是否有交集
|
|
|
|
|
|
needValid = hasSameEM(runtimeTypeEnums, runtime);
|
|
|
|
|
|
}
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
if (!needValid) {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
//字段值
|
|
|
|
|
|
Object value = getValue(t, field.getName());
|
|
|
|
|
|
ValidTypeEnum type = rule.type();
|
|
|
|
|
|
int labelId = rule.labelId();
|
|
|
|
|
|
String message = rule.message();
|
|
|
|
|
|
boolean require = rule.require();
|
|
|
|
|
|
int max = rule.max();
|
|
|
|
|
|
int min = rule.min();
|
|
|
|
|
|
String pattern = rule.pattern();
|
|
|
|
|
|
|
|
|
|
|
|
if (require) {
|
|
|
|
|
|
if (!notNull(value)) {
|
|
|
|
|
|
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(labelId, message));
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
2022-03-22 10:42:26 +08:00
|
|
|
|
}
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
if (ValidTypeEnum.STRING == type) {
|
|
|
|
|
|
//区间值
|
|
|
|
|
|
if (value != null && max != -1) {
|
|
|
|
|
|
String s = String.valueOf(value);
|
|
|
|
|
|
if (s.length() > max) {
|
|
|
|
|
|
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(labelId, message));
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
if (value != null && min != -1) {
|
|
|
|
|
|
String s = String.valueOf(value);
|
|
|
|
|
|
if (s.length() < min) {
|
2022-03-21 20:09:10 +08:00
|
|
|
|
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(labelId, message));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-03-22 10:42:26 +08:00
|
|
|
|
}
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
if (ValidTypeEnum.DATE == type) {
|
|
|
|
|
|
if (value != null && StringUtils.isNotBlank(value.toString()) && isValidDate(value.toString(), pattern)) {
|
|
|
|
|
|
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(labelId, message));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-03-21 20:09:10 +08:00
|
|
|
|
|
2022-03-22 10:42:26 +08:00
|
|
|
|
|
|
|
|
|
|
if (ValidTypeEnum.NUMBER == type) {
|
|
|
|
|
|
if (value instanceof Integer) {
|
|
|
|
|
|
int v = (Integer) value;
|
|
|
|
|
|
if (max != -1) {
|
|
|
|
|
|
if (v > max) {
|
|
|
|
|
|
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(labelId, message));
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
2022-03-22 10:42:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (min != -1) {
|
|
|
|
|
|
if (v < min) {
|
|
|
|
|
|
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(labelId, message));
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2022-03-22 10:42:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static boolean hasSameEM(RuntimeTypeEnum[] runtimeTypeEnums, RuntimeTypeEnum[] runtime) {
|
|
|
|
|
|
boolean needValid = false;
|
|
|
|
|
|
HashSet<RuntimeTypeEnum> set = new HashSet<>(Arrays.asList(runtimeTypeEnums));
|
|
|
|
|
|
set.retainAll(Arrays.asList(runtime));
|
|
|
|
|
|
if (set.size() > 0) {
|
|
|
|
|
|
needValid = true;
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
2022-03-22 10:42:26 +08:00
|
|
|
|
return needValid;
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static <T> Object getValue(T t, String fieldName) {
|
|
|
|
|
|
Object value = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
|
|
|
|
|
|
PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
|
|
|
|
|
|
for (PropertyDescriptor property : props) {
|
|
|
|
|
|
if (fieldName.equals(property.getName())) {
|
|
|
|
|
|
Method method = property.getReadMethod();
|
|
|
|
|
|
value = method.invoke(t, new Object[]{});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
e.printStackTrace();
|
2024-05-06 16:03:29 +08:00
|
|
|
|
log.error("获取属性值失败", e);
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 19:06:43 +08:00
|
|
|
|
private static <T> void setValue(T t, String fieldName, Object value) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
|
|
|
|
|
|
PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
|
|
|
|
|
|
for (PropertyDescriptor property : props) {
|
|
|
|
|
|
if (fieldName.equals(property.getName())) {
|
|
|
|
|
|
Method method = property.getWriteMethod();
|
|
|
|
|
|
method.invoke(t, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-21 20:09:10 +08:00
|
|
|
|
private static boolean notNull(Object value) {
|
|
|
|
|
|
if (null == value) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value instanceof String && isEmpty((String) value)) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value instanceof List && isEmpty((Collection<?>) value)) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static boolean isEmpty(String str) {
|
|
|
|
|
|
return null == str || str.isEmpty();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static boolean isEmpty(Collection<?> list) {
|
|
|
|
|
|
return null == list || list.isEmpty();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 校验日期
|
|
|
|
|
|
*/
|
|
|
|
|
|
private static boolean isValidDate(String str, String pattern) {
|
|
|
|
|
|
boolean convertSuccess = true;
|
|
|
|
|
|
if (str != null && str.length() == pattern.length()) {
|
|
|
|
|
|
// 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写;
|
|
|
|
|
|
SimpleDateFormat format = new SimpleDateFormat(pattern);
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 设置lenient为false.
|
|
|
|
|
|
// 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
|
|
|
|
|
|
format.setLenient(false);
|
|
|
|
|
|
Date dateStr = format.parse(str);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
|
|
|
|
|
|
convertSuccess = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
convertSuccess = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return convertSuccess;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-06 16:03:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 处理参数值,trim,xss
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param t
|
|
|
|
|
|
* @param <T>
|
|
|
|
|
|
*/
|
2023-11-07 19:06:43 +08:00
|
|
|
|
public static <T> void modify(T t) {
|
|
|
|
|
|
Class<?> clazz = t.getClass();
|
|
|
|
|
|
Field[] fields = clazz.getDeclaredFields();
|
|
|
|
|
|
for (Field field : fields) {
|
|
|
|
|
|
Modify rule = field.getDeclaredAnnotation(Modify.class);
|
|
|
|
|
|
|
|
|
|
|
|
if (null == rule) {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ModifyTypeEnum[] modifyTypeEnums = rule.modifyType();
|
|
|
|
|
|
ValueTypeEnum valueTypeEnum = rule.valueType();
|
|
|
|
|
|
for (int i = 0; i < modifyTypeEnums.length; i++) {
|
|
|
|
|
|
Object value = getValue(t, field.getName());
|
|
|
|
|
|
if (valueTypeEnum == ValueTypeEnum.STRING) {
|
|
|
|
|
|
String result = value.toString();
|
|
|
|
|
|
|
|
|
|
|
|
if (modifyTypeEnums[i] == ModifyTypeEnum.TRIM) {
|
|
|
|
|
|
result = result.trim();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (modifyTypeEnums[i] == ModifyTypeEnum.RESTORE_SQL) {
|
|
|
|
|
|
result = result.replace("select", "select")
|
|
|
|
|
|
.replace("SELECT", "SELECT")
|
|
|
|
|
|
.replace("join", "join")
|
|
|
|
|
|
.replace("JOIN", "JOIN")
|
|
|
|
|
|
.replace("and", "and")
|
|
|
|
|
|
.replace("AND", "AND")
|
|
|
|
|
|
.replace("or", "or")
|
|
|
|
|
|
.replace("OR", "OR")
|
|
|
|
|
|
.replace("in", "in")
|
|
|
|
|
|
.replace("IN", "IN")
|
|
|
|
|
|
.replace("like", "like")
|
2024-04-10 14:20:30 +08:00
|
|
|
|
.replace("LIKE", "LIKE")
|
2023-11-07 19:06:43 +08:00
|
|
|
|
.replace("exists", "exists")
|
|
|
|
|
|
.replace("EXISTS", "EXISTS")
|
|
|
|
|
|
.replace("between", "between")
|
|
|
|
|
|
.replace("BETWEEN", "BETWEEN")
|
|
|
|
|
|
.replace("union", "union")
|
2025-04-28 18:14:17 +08:00
|
|
|
|
.replace("UNION", "UNION")
|
|
|
|
|
|
.replace("substr", "substr")
|
|
|
|
|
|
.replace("SUBSTR", "SUBSTR");
|
2023-11-07 19:06:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
setValue(t, field.getName(), result);
|
|
|
|
|
|
} else if (valueTypeEnum == ValueTypeEnum.OBJECT) {
|
|
|
|
|
|
modify(value);
|
|
|
|
|
|
} else if (valueTypeEnum == ValueTypeEnum.ARRAY) {
|
|
|
|
|
|
Collection list = (Collection) value;
|
|
|
|
|
|
list.forEach(l -> modify(l));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-06 16:03:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 比较两个对象,如果值不相等,则抛出异常
|
|
|
|
|
|
* <p>
|
|
|
|
|
|
* true代表相等,false代表不相等
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param o
|
|
|
|
|
|
* @param n
|
|
|
|
|
|
* @param <T>
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static <T> boolean compare(T o, T n) {
|
|
|
|
|
|
Class<?> clazz = o.getClass();
|
|
|
|
|
|
Field[] fields = clazz.getDeclaredFields();
|
|
|
|
|
|
boolean result = true;
|
|
|
|
|
|
for (Field field : fields) {
|
|
|
|
|
|
Compare rule = field.getDeclaredAnnotation(Compare.class);
|
|
|
|
|
|
if (null == rule) {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
boolean reportError = rule.reportError();
|
|
|
|
|
|
String message = rule.message();
|
|
|
|
|
|
|
|
|
|
|
|
ValueTypeEnum valueTypeEnum = rule.type();
|
|
|
|
|
|
Object oValue = getValue(o, field.getName());
|
|
|
|
|
|
Object nValue = getValue(n, field.getName());
|
|
|
|
|
|
if (valueTypeEnum == ValueTypeEnum.STRING) {
|
|
|
|
|
|
result = result && StrUtil.equals(Util.null2String(oValue), Util.null2String(nValue));
|
|
|
|
|
|
if (!result && reportError) {
|
|
|
|
|
|
throw new RuntimeException(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (valueTypeEnum == ValueTypeEnum.DATE) {
|
|
|
|
|
|
result = result && DateUtil.compare((Date) o, (Date) n) == 0;
|
|
|
|
|
|
if (!result && reportError) {
|
|
|
|
|
|
throw new RuntimeException(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (valueTypeEnum == ValueTypeEnum.OBJECT) {
|
|
|
|
|
|
result = result && compare(oValue, nValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 19:06:43 +08:00
|
|
|
|
|
2022-03-21 20:09:10 +08:00
|
|
|
|
}
|