|
@@ -186,92 +186,202 @@ public class ParamCheckAspect {
|
|
|
|
|
|
/**
|
|
|
* 是否数字类型
|
|
|
- *
|
|
|
- * @param typeName
|
|
|
- * @return
|
|
|
- */
|
|
|
- private boolean isNumberType(String typeName) {
|
|
|
- if ("integer".equalsIgnoreCase(typeName) || ParamType.INT.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- } else if ("long".equalsIgnoreCase(typeName) || ParamType.LONG.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- } else if ("double".equalsIgnoreCase(typeName) || ParamType.DOUBLE.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- } else if ("float".equalsIgnoreCase(typeName) || ParamType.FLOAT.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- } else if ("byte".equalsIgnoreCase(typeName) || ParamType.BYTE.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- } else if ("short".equalsIgnoreCase(typeName) || ParamType.SHORT.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- } else if ("character".equalsIgnoreCase(typeName) || ParamType.CHAR.name().equalsIgnoreCase(typeName)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查String类型的参数
|
|
|
- * 包括 size/根据 type 检查 min/max/pattern
|
|
|
- *
|
|
|
- * @param value
|
|
|
- * @param paramCheck
|
|
|
- */
|
|
|
- private void checkString(String value, ParamCheck paramCheck) throws AtdsException {
|
|
|
- // 检查长度
|
|
|
- if (paramCheck.size() < value.length()) {
|
|
|
- throw new AtdsException("parameter %s is too long. (" + value.length() + " of " + paramCheck.size() + ")");
|
|
|
- }
|
|
|
- // 日期时
|
|
|
- if (ParamType.DATE.equals(paramCheck.type())) {
|
|
|
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern(paramCheck.pattern());
|
|
|
- try {
|
|
|
- formatter.parse(value);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new AtdsException("parameter %s needs correct pattern. (" + paramCheck.pattern() + ")");
|
|
|
- }
|
|
|
- } else if (ParamType.BOOLEAN.equals(paramCheck.type())) {
|
|
|
- if (!"true".equals(value) && !"false".equals(value)) {
|
|
|
- throw new AtdsException("parameter %s is not a " + paramCheck.type());
|
|
|
- }
|
|
|
- } else if (isNumberType(paramCheck.type().name())) {
|
|
|
- checkNumber(value, paramCheck);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查数字类型(BYTE/SHORT/INT/LONG/FLOAT/DOUBLE)以及字符类型的参数
|
|
|
- * 包括 min/max
|
|
|
- *
|
|
|
- * @param value
|
|
|
- * @param paramCheck
|
|
|
- */
|
|
|
- private void checkNumber(Object value, ParamCheck paramCheck) {
|
|
|
- BigDecimal numberValue;
|
|
|
- try {
|
|
|
- String stringValue = value.toString();
|
|
|
- if (ParamType.CHAR.equals(paramCheck.type())) {
|
|
|
- if (stringValue.length() != 1) {
|
|
|
- throw new NumberFormatException();
|
|
|
- }
|
|
|
- numberValue = new BigDecimal(stringValue.toCharArray()[0]);
|
|
|
- } else {
|
|
|
- numberValue = new BigDecimal(stringValue);
|
|
|
- }
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- throw new AtdsException("parameter %s is not a " + paramCheck.type());
|
|
|
- }
|
|
|
- // 检查最大值
|
|
|
- BigDecimal min = new BigDecimal(paramCheck.min());
|
|
|
- if (numberValue.compareTo(min) < 0) {
|
|
|
- throw new AtdsException("parameter %s is out of range. (min: " + paramCheck.min() + ")");
|
|
|
- }
|
|
|
- // 检查最小值
|
|
|
- BigDecimal max = new BigDecimal(paramCheck.max());
|
|
|
- if (numberValue.compareTo(max) > 0) {
|
|
|
- throw new AtdsException("parameter %s is out of range. (max: " + paramCheck.max() + ")");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
+ */**
|
|
|
+ * @author : wangzhiyong
|
|
|
+ * @date : 2018/11/12 17:58
|
|
|
+ * description : 参数校验
|
|
|
+ */
|
|
|
+ @Aspect
|
|
|
+ @Component
|
|
|
+ public class ParamCheckAspect {
|
|
|
+
|
|
|
+ private static final Logger logger = Logger.getLogger(ParamCheckAspect.class);
|
|
|
+
|
|
|
+ //todo 暂时使用 方法扫描 以 O 结尾的方法 标识对外的接口 后期改为 @args
|
|
|
+ // @Pointcut("@args(com.ys.atds.annotation.ParamCheck)")
|
|
|
+ @Pointcut("execution(* com.ys.*.api.impl..*.*O(..))")
|
|
|
+ public void paramPointcut() {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Before("paramPointcut()")
|
|
|
+ public void before(JoinPoint joinPoint) {
|
|
|
+ Object[] args = joinPoint.getArgs();
|
|
|
+ if (args == null || args.length == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 方法的参数
|
|
|
+ Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
|
|
|
+ for (int i = 0; i < parameterTypes.length; i++) {
|
|
|
+ Class<?> parameterType = parameterTypes[i];
|
|
|
+ // 若参数未注解ParamCheck, 忽略验证
|
|
|
+ if (parameterType.getAnnotation(ParamCheck.class) == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 传入的参数
|
|
|
+ Object arg = args[i];
|
|
|
+ if (arg == null) {
|
|
|
+ throw new AtdsException("parameter should not be null or empty");
|
|
|
+ }
|
|
|
+ //获取所有变量
|
|
|
+ List<Field> fieldList = new ArrayList<>();
|
|
|
+ Class<?> argClass = arg.getClass();
|
|
|
+ // 去重临时变量
|
|
|
+ Set<String> temp = new HashSet<>();
|
|
|
+ //当父类为null的时候说明到达了最上层的父类(Object类).
|
|
|
+ while (argClass != null && !argClass.getName().toLowerCase().equals("java.lang.object")) {
|
|
|
+ for (Field field : argClass.getDeclaredFields()) {
|
|
|
+ if (!temp.contains(field.getName())) {
|
|
|
+ fieldList.add(field);
|
|
|
+ temp.add(field.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //得到父类,然后赋给自己
|
|
|
+ argClass = argClass.getSuperclass();
|
|
|
+ }
|
|
|
+ // 获取注解
|
|
|
+ for (Field field : fieldList) {
|
|
|
+ // 获取注解
|
|
|
+ ParamCheck annotationsByType = field.getAnnotation(ParamCheck.class);
|
|
|
+ // 只检查@ParamCheck注解字段
|
|
|
+ if (annotationsByType == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 设置字段可访问并取值
|
|
|
+ field.setAccessible(true);
|
|
|
+ Object argValue = null;
|
|
|
+ try {
|
|
|
+ argValue = field.get(arg);
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ logger.error("ParamCheckAspect: " + e.getMessage());
|
|
|
+ }
|
|
|
+ // 字段类型
|
|
|
+ Class type = field.getType();
|
|
|
+ // 字段为null或空string
|
|
|
+ if (argValue == null || (String.class.equals(type) && "".equals(argValue))) {
|
|
|
+ // 若注解声明非空, 抛出异常, 否则忽略本字段
|
|
|
+ if (annotationsByType.require()) {
|
|
|
+ throw new AtdsException("parameter " + field.getName() + " should not be null or empty");
|
|
|
+ } else {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 字段类型非数字 且非String, 忽略本字段, 不深入检查
|
|
|
+ if (!isNumberType(type) && !String.class.equals(type)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 字段类型为 String 或 数字, 走各自验证
|
|
|
+ if (String.class.equals(type)) {
|
|
|
+ checkString(String.valueOf(argValue), annotationsByType);
|
|
|
+ } else {
|
|
|
+ checkNumber(argValue, annotationsByType);
|
|
|
+ }
|
|
|
+ } catch (AtdsException e) {
|
|
|
+ throw new AtdsException(String.format(e.getMessage(), field.getName()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否数字类型
|
|
|
+ *
|
|
|
+ * @param type
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isNumberType(Class type) {
|
|
|
+ return isNumberType(type.getSimpleName());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否数字类型
|
|
|
+ *
|
|
|
+ * @param typeName
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isNumberType(String typeName) {
|
|
|
+ if ("integer".equalsIgnoreCase(typeName) || ParamType.INT.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ } else if ("long".equalsIgnoreCase(typeName) || ParamType.LONG.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ } else if ("double".equalsIgnoreCase(typeName) || ParamType.DOUBLE.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ } else if ("float".equalsIgnoreCase(typeName) || ParamType.FLOAT.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ } else if ("byte".equalsIgnoreCase(typeName) || ParamType.BYTE.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ } else if ("short".equalsIgnoreCase(typeName) || ParamType.SHORT.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ } else if ("character".equalsIgnoreCase(typeName) || ParamType.CHAR.name().equalsIgnoreCase(typeName)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查String类型的参数
|
|
|
+ * 包括 size/根据 type 检查 min/max/pattern
|
|
|
+ *
|
|
|
+ * @param value
|
|
|
+ * @param paramCheck
|
|
|
+ */
|
|
|
+ private void checkString(String value, ParamCheck paramCheck) throws AtdsException {
|
|
|
+ // 检查长度
|
|
|
+ if (paramCheck.size() < value.length()) {
|
|
|
+ throw new AtdsException("parameter %s is too long. (" + value.length() + " of " + paramCheck.size() + ")");
|
|
|
+ }
|
|
|
+ // 日期时
|
|
|
+ if (ParamType.DATE.equals(paramCheck.type())) {
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(paramCheck.pattern());
|
|
|
+ try {
|
|
|
+ formatter.parse(value);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new AtdsException("parameter %s needs correct pattern. (" + paramCheck.pattern() + ")");
|
|
|
+ }
|
|
|
+ } else if (ParamType.BOOLEAN.equals(paramCheck.type())) {
|
|
|
+ if (!"true".equals(value) && !"false".equals(value)) {
|
|
|
+ throw new AtdsException("parameter %s is not a " + paramCheck.type());
|
|
|
+ }
|
|
|
+ } else if (isNumberType(paramCheck.type().name())) {
|
|
|
+ checkNumber(value, paramCheck);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查数字类型(BYTE/SHORT/INT/LONG/FLOAT/DOUBLE)以及字符类型的参数
|
|
|
+ * 包括 min/max
|
|
|
+ *
|
|
|
+ * @param value
|
|
|
+ * @param paramCheck
|
|
|
+ */
|
|
|
+ private void checkNumber(Object value, ParamCheck paramCheck) {
|
|
|
+ BigDecimal numberValue;
|
|
|
+ try {
|
|
|
+ String stringValue = value.toString();
|
|
|
+ if (ParamType.CHAR.equals(paramCheck.type())) {
|
|
|
+ if (stringValue.length() != 1) {
|
|
|
+ throw new NumberFormatException();
|
|
|
+ }
|
|
|
+ numberValue = new BigDecimal(stringValue.toCharArray()[0]);
|
|
|
+ } else {
|
|
|
+ numberValue = new BigDecimal(stringValue);
|
|
|
+ }
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ throw new AtdsException("parameter %s is not a " + paramCheck.type());
|
|
|
+ }
|
|
|
+ // 检查最大值
|
|
|
+ BigDecimal min = new BigDecimal(paramCheck.min());
|
|
|
+ if (numberValue.compareTo(min) < 0) {
|
|
|
+ throw new AtdsException("parameter %s is out of range. (min: " + paramCheck.min() + ")");
|
|
|
+ }
|
|
|
+ // 检查最小值
|
|
|
+ BigDecimal max = new BigDecimal(paramCheck.max());
|
|
|
+ if (numberValue.compareTo(max) > 0) {
|
|
|
+ throw new AtdsException("parameter %s is out of range. (max: " + paramCheck.max() + ")");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
```
|