title: aop date: 2018-12-03 15:38:33 tags: [Spring Boot,AOP]
通过自定义注解和aop实现参数校验.
mvc 配置文件 添加
<aop:aspectj-autoproxy proxy-target-class="true"/>
开启自动切面代理
添加自定义注解 ```java /**
/**
/**
/**
/**
/**
/**
/**
}
- 添加指定类型
```java
public enum ParamType {
/**
* 基本参数类型
*/
BYTE,SHORT,INT,LONG,FLOAT,DOUBLE,BOOLEAN,CHAR,
/**
* 拓展参数类型
*/
STRING,DATE
}
添加处理逻辑 ```java @Aspect @Component public class ParamCheckAspect {
private static final Logger logger = Logger.getLogger(ParamCheckAspect.class);
@Pointcut("@args(com.dragon.chaofeng.annotation.ParamCheck, ..) && execution(* com.dragon.chaofeng.web...(..))") // @Pointcut("execution(* com.dragon.chaofeng.web...(..))") // @Pointcut("@args(org.springframework.web.bind.annotation.RequestBody, ..)") // @Pointcut("@within(com.dragon.chaofeng.annotation.ParamCheck)") // @Pointcut("execution (* com.dragon.chaofeng.service...(..))") // @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)") 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()));
}
}
}
}
/**
/**
/**
}
/**
} ```