diff --git a/basic-util/pom.xml b/basic-util/pom.xml index ff8665e4..8519202c 100644 --- a/basic-util/pom.xml +++ b/basic-util/pom.xml @@ -128,6 +128,16 @@ + + ink.wgink + basic-annotation + 1.0-SNAPSHOT + + + ink.wgink + basic-exception + 1.0-SNAPSHOT + ink.wgink basic-pojo diff --git a/basic-util/src/main/java/ink/wgink/util/BeanPropertyCheckUtil.java b/basic-util/src/main/java/ink/wgink/util/BeanPropertyCheckUtil.java new file mode 100644 index 00000000..0a9883f0 --- /dev/null +++ b/basic-util/src/main/java/ink/wgink/util/BeanPropertyCheckUtil.java @@ -0,0 +1,247 @@ +package ink.wgink.util; + +import ink.wgink.annotation.*; +import ink.wgink.exceptions.ParamsException; +import ink.wgink.exceptions.base.SystemException; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @ClassName: BeanPropertyCheckUtil + * @Description: 对象属性检查工具 + * @Author: wanggeng + * @Date: 2021/8/19 2:03 下午 + * @Version: 1.0 + */ +public class BeanPropertyCheckUtil { + + /** + * 校验字段 + * + * @param object + * @throws ParamsException + */ + public static void checkField(Object object) throws ParamsException { + if (object == null) { + return; + } + Class clazz = object.getClass(); + List fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())); + setSuperClassField(clazz, fields); + Method[] methods = clazz.getMethods(); + try { + for (Field field : fields) { + Method method = getGetMethodByField(methods, field.getName()); + if (method == null) { + continue; + } + Object fieldValue = method.invoke(object); + if (field.isAnnotationPresent(CheckNullAnnotation.class)) { + CheckNullAnnotation checkNullAnnotation = field.getAnnotation(CheckNullAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s不能为空", checkNullAnnotation.name())); + } + checkTypes(checkNullAnnotation.name(), fieldValue.toString(), checkNullAnnotation.types()); + } else if (field.isAnnotationPresent(CheckEmptyAnnotation.class)) { + CheckEmptyAnnotation checkEmptyAnnotation = field.getAnnotation(CheckEmptyAnnotation.class); + if (fieldValue == null || StringUtils.isBlank(fieldValue.toString())) { + throw new ParamsException(String.format("%s不能为空或空串", checkEmptyAnnotation.name())); + } + checkRegular(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.verifyType(), checkEmptyAnnotation.regex()); + checkTypes(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.types()); + } else if (field.isAnnotationPresent(CheckNumberAnnotation.class)) { + CheckNumberAnnotation checkNumberAnnotation = field.getAnnotation(CheckNumberAnnotation.class); + if (fieldValue == null || !NumberUtils.isNumber(fieldValue.toString())) { + throw new ParamsException(String.format("%s必须为数字", checkNumberAnnotation.name())); + } + Double value = Double.parseDouble(fieldValue.toString()); + if (value < checkNumberAnnotation.min()) { + throw new ParamsException(String.format("%s最小值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.min())); + } + if (value > checkNumberAnnotation.max()) { + throw new ParamsException(String.format("%s最大值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.max())); + } + checkTypes(checkNumberAnnotation.name(), fieldValue.toString(), checkNumberAnnotation.types()); + } else if (field.isAnnotationPresent(CheckBooleanAnnotation.class)) { + CheckBooleanAnnotation checkBooleanAnnotation = field.getAnnotation(CheckBooleanAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s必须为布尔", checkBooleanAnnotation.name())); + } + checkTypes(checkBooleanAnnotation.name(), fieldValue.toString(), checkBooleanAnnotation.types()); + } else if (field.isAnnotationPresent(CheckListAnnotation.class)) { + CheckListAnnotation checkListAnnotation = field.getAnnotation(CheckListAnnotation.class); + if (fieldValue == null) { + throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); + } + if (fieldValue instanceof List) { + List fieldValueList = (List) fieldValue; + if (fieldValueList.isEmpty()) { + throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); + } + } + } + if (field.isAnnotationPresent(CheckBeanAnnotation.class)) { + if (fieldValue == null) { + continue; + } + checkField(fieldValue); + } + if (field.isAnnotationPresent(CheckListBeanAnnotation.class)) { + if (fieldValue instanceof List) { + List fieldValueList = (List) fieldValue; + if (fieldValueList == null || fieldValueList.isEmpty()) { + continue; + } + for (Object obj : fieldValueList) { + checkField(obj); + } + } + } + } + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + throw new SystemException("系统错误"); + } + } + + /** + * 检查类型 + * + * @param name + * @param value + * @param types + * @throws ParamsException + */ + private static void checkTypes(String name, String value, String[] types) throws ParamsException { + if (types != null && types.length > 0) { + StringBuilder typeSB = new StringBuilder(); + for (String type : types) { + if (StringUtils.equals(value, type)) { + return; + } + if (typeSB.length() > 0) { + typeSB.append(","); + } + typeSB.append("\"").append(type).append("\""); + } + throw new ParamsException(String.format("%s必须是如下类型:[%s]", name, typeSB.toString())); + } + } + + /** + * 检查正则 + * + * @param name + * @param value + * @param verifyType + * @param regex + */ + private static void checkRegular(String name, String value, String verifyType, String regex) { + if (StringUtils.isBlank(verifyType)) { + return; + } + if (StringUtils.equals("username", verifyType)) { + if (!RegexUtil.isUsername(value)) { + throw new ParamsException(String.format("%s格式只能包含字母、数字、-_!@#%.", name)); + } + return; + } else if (StringUtils.equals("phone", verifyType)) { + if (!RegexUtil.isPhone(value)) { + throw new ParamsException(String.format("%s格式非手机格式", name)); + } + return; + } else if (StringUtils.equals("email", verifyType)) { + if (!RegexUtil.isEmail(value)) { + throw new ParamsException(String.format("%s格式非邮件格式", name)); + } + return; + } else if (StringUtils.equals("url", verifyType)) { + if (!RegexUtil.isUrl(value)) { + throw new ParamsException(String.format("%s格式非url格式", name)); + } + return; + } else if (StringUtils.equals("number", verifyType)) { + if (!NumberUtils.isNumber(value)) { + throw new ParamsException(String.format("%s格式非数字格式", name)); + } + return; + } else if (StringUtils.equals("date", verifyType)) { + if (!RegexUtil.isDate(value)) { + throw new ParamsException(String.format("%s格式非日期格式", name)); + } + return; + } else if (StringUtils.equals("datetime", verifyType)) { + if (!RegexUtil.isDatetime(value)) { + throw new ParamsException(String.format("%s格式非时间戳格式", name)); + } + return; + } else if (StringUtils.equals("identity", verifyType)) { + if (!RegexUtil.isIdentity(value)) { + throw new ParamsException(String.format("%s格式非身份证格式", name)); + } + return; + } else if (StringUtils.equals("letter", verifyType)) { + if (!RegexUtil.isLetter(value)) { + throw new ParamsException(String.format("%s格式非字母格式", name)); + } + return; + } else if (StringUtils.equals("chinese", verifyType)) { + if (!RegexUtil.isLetter(value)) { + throw new ParamsException(String.format("%s格式非中文格式", name)); + } + return; + } else if (StringUtils.equals("custom", verifyType)) { + if (StringUtils.isBlank(regex)) { + return; + } + if (!Pattern.compile(regex).matcher(value).matches()) { + throw new ParamsException(String.format("%s格式不正确", name)); + } + } + } + + /** + * 通过字段获取get方法 + * + * @param methods + * @param fieldName + * @return + */ + public static Method getGetMethodByField(Method[] methods, String fieldName) { + String getMethodName = String.format("get%s", fieldName).toLowerCase(); + for (Method method : methods) { + if (StringUtils.equals(getMethodName, method.getName().toLowerCase())) { + return method; + } + } + return null; + } + + /** + * 设置父类属性列表 + * + * @param clazz + * @param fields + */ + private static void setSuperClassField(Class clazz, List fields) { + Class superClazz = clazz.getSuperclass(); + if (superClazz == null) { + return; + } + Field[] superFields = superClazz.getDeclaredFields(); + if (superFields == null) { + return; + } + fields.addAll(Arrays.asList(superFields)); + setSuperClassField(superClazz, fields); + } + +} diff --git a/common/pom.xml b/common/pom.xml index 3f29940d..26fe3f9c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -22,16 +22,6 @@ basic-util 1.0-SNAPSHOT - - ink.wgink - basic-exception - 1.0-SNAPSHOT - - - ink.wgink - basic-annotation - 1.0-SNAPSHOT - ink.wgink basic-properties diff --git a/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java b/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java index ff690cb7..64cea5ed 100644 --- a/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java +++ b/common/src/main/java/ink/wgink/common/aspect/ApiParamsAspect.java @@ -1,10 +1,9 @@ package ink.wgink.common.aspect; -import ink.wgink.annotation.*; +import ink.wgink.annotation.CheckRequestBodyAnnotation; import ink.wgink.exceptions.ParamsException; -import ink.wgink.util.RegexUtil; +import ink.wgink.util.BeanPropertyCheckUtil; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Aspect; @@ -16,14 +15,8 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestBody; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; /** * When you feel like quitting. Think about why you started @@ -66,7 +59,7 @@ public class ApiParamsAspect { if (parameter.isAnnotationPresent(RequestBody.class)) { for (Object arg : args) { if (parameter.getType() == arg.getClass()) { - checkField(arg); + BeanPropertyCheckUtil.checkField(arg); } } } @@ -98,213 +91,5 @@ public class ApiParamsAspect { return null; } - /** - * 校验字段 - * - * @param object - * @throws ParamsException - */ - public void checkField(Object object) throws ParamsException { - Class clazz = object.getClass(); - List fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())); - setSuperClassField(clazz, fields); - Method[] methods = clazz.getMethods(); - try { - for (Field field : fields) { - Method method = getGetMethodByField(methods, field.getName()); - if (method == null) { - continue; - } - Object fieldValue = method.invoke(object); - if (field.isAnnotationPresent(CheckNullAnnotation.class)) { - CheckNullAnnotation checkNullAnnotation = field.getAnnotation(CheckNullAnnotation.class); - if (fieldValue == null) { - throw new ParamsException(String.format("%s不能为空", checkNullAnnotation.name())); - } - checkTypes(checkNullAnnotation.name(), fieldValue.toString(), checkNullAnnotation.types()); - } else if (field.isAnnotationPresent(CheckEmptyAnnotation.class)) { - CheckEmptyAnnotation checkEmptyAnnotation = field.getAnnotation(CheckEmptyAnnotation.class); - if (fieldValue == null || StringUtils.isBlank(fieldValue.toString())) { - throw new ParamsException(String.format("%s不能为空或空串", checkEmptyAnnotation.name())); - } - checkRegular(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.verifyType(), checkEmptyAnnotation.regex()); - checkTypes(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.types()); - } else if (field.isAnnotationPresent(CheckNumberAnnotation.class)) { - CheckNumberAnnotation checkNumberAnnotation = field.getAnnotation(CheckNumberAnnotation.class); - if (fieldValue == null || !NumberUtils.isNumber(fieldValue.toString())) { - throw new ParamsException(String.format("%s必须为数字", checkNumberAnnotation.name())); - } - Double value = Double.parseDouble(fieldValue.toString()); - if (value < checkNumberAnnotation.min()) { - throw new ParamsException(String.format("%s最小值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.min())); - } - if (value > checkNumberAnnotation.max()) { - throw new ParamsException(String.format("%s最大值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.max())); - } - checkTypes(checkNumberAnnotation.name(), fieldValue.toString(), checkNumberAnnotation.types()); - } else if (field.isAnnotationPresent(CheckBooleanAnnotation.class)) { - CheckBooleanAnnotation checkBooleanAnnotation = field.getAnnotation(CheckBooleanAnnotation.class); - if (fieldValue == null) { - throw new ParamsException(String.format("%s必须为布尔", checkBooleanAnnotation.name())); - } - checkTypes(checkBooleanAnnotation.name(), fieldValue.toString(), checkBooleanAnnotation.types()); - } else if (field.isAnnotationPresent(CheckListAnnotation.class)) { - CheckListAnnotation checkListAnnotation = field.getAnnotation(CheckListAnnotation.class); - if (fieldValue == null) { - throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); - } - if (fieldValue instanceof List) { - List fieldValueList = (List) fieldValue; - if (fieldValueList.isEmpty()) { - throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name())); - } - for (Object obj : fieldValueList) { - checkField(obj); - } - } else if (fieldValue instanceof String[]) { - String[] fieldValueArray = (String[]) fieldValue; - for (Object obj : fieldValueArray) { - checkField(obj); - } - } - } - } - } catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - throw new ParamsException("系统错误"); - } - } - - /** - * 检查类型 - * - * @param name - * @param value - * @param types - * @throws ParamsException - */ - private void checkTypes(String name, String value, String[] types) throws ParamsException { - if (types != null && types.length > 0) { - StringBuilder typeSB = new StringBuilder(); - for (String type : types) { - if (StringUtils.equals(value, type)) { - return; - } - if (typeSB.length() > 0) { - typeSB.append(","); - } - typeSB.append("\"").append(type).append("\""); - } - throw new ParamsException(String.format("%s必须是如下类型:[%s]", name, typeSB.toString())); - } - } - - /** - * 检查正则 - * - * @param name - * @param value - * @param verifyType - * @param regex - */ - private void checkRegular(String name, String value, String verifyType, String regex) { - if (StringUtils.isBlank(verifyType)) { - return; - } - if (StringUtils.equals("username", verifyType)) { - if (!RegexUtil.isUsername(value)) { - throw new ParamsException(String.format("%s格式只能包含字母、数字、-_!@#%.", name)); - } - return; - } else if (StringUtils.equals("phone", verifyType)) { - if (!RegexUtil.isPhone(value)) { - throw new ParamsException(String.format("%s格式非手机格式", name)); - } - return; - } else if (StringUtils.equals("email", verifyType)) { - if (!RegexUtil.isEmail(value)) { - throw new ParamsException(String.format("%s格式非邮件格式", name)); - } - return; - } else if (StringUtils.equals("url", verifyType)) { - if (!RegexUtil.isUrl(value)) { - throw new ParamsException(String.format("%s格式非url格式", name)); - } - return; - } else if (StringUtils.equals("number", verifyType)) { - if (!NumberUtils.isNumber(value)) { - throw new ParamsException(String.format("%s格式非数字格式", name)); - } - return; - } else if (StringUtils.equals("date", verifyType)) { - if (!RegexUtil.isDate(value)) { - throw new ParamsException(String.format("%s格式非日期格式", name)); - } - return; - } else if (StringUtils.equals("datetime", verifyType)) { - if (!RegexUtil.isDatetime(value)) { - throw new ParamsException(String.format("%s格式非时间戳格式", name)); - } - return; - } else if (StringUtils.equals("identity", verifyType)) { - if (!RegexUtil.isIdentity(value)) { - throw new ParamsException(String.format("%s格式非身份证格式", name)); - } - return; - } else if (StringUtils.equals("letter", verifyType)) { - if (!RegexUtil.isLetter(value)) { - throw new ParamsException(String.format("%s格式非字母格式", name)); - } - return; - } else if (StringUtils.equals("chinese", verifyType)) { - if (!RegexUtil.isLetter(value)) { - throw new ParamsException(String.format("%s格式非中文格式", name)); - } - return; - } else if (StringUtils.equals("custom", verifyType)) { - if (StringUtils.isBlank(regex)) { - return; - } - if (!Pattern.compile(regex).matcher(value).matches()) { - throw new ParamsException(String.format("%s格式不正确", name)); - } - } - } - - /** - * 通过字段获取get方法 - * - * @param methods - * @param fieldName - * @return - */ - public Method getGetMethodByField(Method[] methods, String fieldName) { - String getMethodName = String.format("get%s", fieldName).toLowerCase(); - for (Method method : methods) { - if (StringUtils.equals(getMethodName, method.getName().toLowerCase())) { - return method; - } - } - return null; - } - - /** - * 设置父类属性列表 - * - * @param clazz - * @param fields - */ - private void setSuperClassField(Class clazz, List fields) { - Class superClazz = clazz.getSuperclass(); - if (superClazz == null) { - return; - } - Field[] superFields = superClazz.getDeclaredFields(); - if (superFields == null) { - return; - } - fields.addAll(Arrays.asList(superFields)); - setSuperClassField(superClazz, fields); - } }