1、切面依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
2、工具类
/** * @author LiuHuan * @date 2019-11-14 21:07 * @desc 切面工具 */ public class AspectUtil { /** * 参数校验 * @param args * @param method */ public static List<String> checkParam(Object[] args, Method method){ List<String> errorMsgList = Lists.newArrayList(); if (null == args || 0 == args.length || null == method) { return errorMsgList; } Annotation[][] parameterAnnotations = method.getParameterAnnotations(); int index = 0; for (Annotation[] parameterAnnotation : parameterAnnotations) { Object arg = args[index++]; for (Annotation annotation : parameterAnnotation) { if (annotation instanceof NotNull) { if (null == arg) { NotNull notNull = (NotNull)annotation; errorMsgList.add(notNull.name() + notNull.msg()); } } else if (annotation instanceof NotEmpty) { if (checkArgEmpty(arg)) { NotEmpty notEmpty = (NotEmpty)annotation; errorMsgList.add(notEmpty.name() + notEmpty.msg()); } } else if (annotation instanceof VerifyBean) { errorMsgList.addAll(checkBean(arg,((VerifyBean)annotation))); } } } return errorMsgList; } /** * 校验参数是否为empty * @param arg * @return */ private static boolean checkArgEmpty(Object arg) { return null == arg || arg instanceof String && ((String)arg).isEmpty() || arg instanceof Collection && ((Collection)arg).isEmpty() || arg instanceof Map && ((Map)arg).isEmpty(); } /** * 校验bean属性参数合法性 * @param bean * @param verifyBean * @return */ private static List<String> checkBean(Object bean, VerifyBean verifyBean) { List<String> errorMsg = Lists.newArrayList(); if (null == bean) { errorMsg.add(verifyBean.name() + verifyBean.msg()); return errorMsg; } List<Field> fields = getFields(bean.getClass()); //校验bean中的每个参数合法性 for (Field field : fields) { Annotation[] annotations = field.getDeclaredAnnotations(); if (null == annotations || 0 == annotations.length) { continue; } field.setAccessible(true); Object value = null; try { value = field.get(bean); } catch (IllegalAccessException e) { //异常不做处理,取null } for (Annotation annotation : annotations) { if (annotation instanceof NotNull && checkNotNull((NotNull)annotation,verifyBean.type(),value)) { NotNull notNull = (NotNull)annotation; errorMsg.add(field.getName() + notNull.msg()); } else if (annotation instanceof NotEmpty && checkNotEmpty((NotEmpty)annotation,verifyBean.type(),value)) { NotEmpty notEmpty = (NotEmpty)annotation; errorMsg.add(field.getName() + notEmpty.msg()); } } } return errorMsg; } /** * 判断在请求类型相符的情况下参数是否为空 * @param annotation * @param type * @param value * @return */ private static boolean checkNotEmpty(NotEmpty annotation, ServiceTypeEnum type, Object value) { for (ServiceTypeEnum serviceTypeEnum : annotation.type()) { if (serviceTypeEnum.equals(type) || serviceTypeEnum.equals(ServiceTypeEnum.ALL)) { return checkArgEmpty(value); } } return false; } /** * 判断在请求类型相符的情况下参数是否为null * @param annotation * @param type * @param value * @return */ private static boolean checkNotNull(NotNull annotation, ServiceTypeEnum type, Object value) { for (ServiceTypeEnum serviceTypeEnum : annotation.type()) { if (serviceTypeEnum.equals(type) || serviceTypeEnum.equals(ServiceTypeEnum.ALL)) { return null == value; } } return false; } /** * 获取该类所有属性 * @param clazz * @return */ private static List<Field> getFields(Class<?> clazz) { List<Field> fields = Lists.newArrayList(); //获取父类属性 Class<?> superclass = clazz.getSuperclass(); if (null != superclass) { List<Field> supperFields = getFields(superclass); fields.addAll(supperFields); } Field[] declaredFields = clazz.getDeclaredFields(); fields.addAll(Arrays.asList(declaredFields)); return fields; } }
3、切面
/** * @author LiuHuan * @date 2019-11-14 21:15 * @desc 数据校验切面 */ @Component @Aspect public class RequestParamAspect { private static Logger logger = LoggerFactory.getLogger(RequestParamAspect.class); @Pointcut("execution(* com.cainiao.finance.customer.facade.api.*.*(..))") public void serviceBefore(){} /** * 方法执行前校验参数合法性 * @param point */ @Before("serviceBefore()") public void before(JoinPoint point){ Method method = ((MethodSignature)point.getSignature()).getMethod(); List<String> errorList = AspectUtil.checkParam(point.getArgs(), method); if (!errorList.isEmpty()) { logger.error("{}#{} param invalid, reason:{}",method.getDeclaringClass().getSimpleName(), method.getName(), errorList.toString()); throw new ParamException(errorList); } } }
4、注解
/** * @author LiuHuan * @date 2019-11-14 21:06 * @desc 字段非空校验 */ @Target(value = {ElementType.FIELD,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface NotEmpty { ServiceTypeEnum[] type() default {ServiceTypeEnum.ALL}; /** * 参数名 * @return */ String name() default ""; /** * 报错信息 * @return */ String msg() default "不能为空"; } /** * @author LiuHuan * @date 2019-11-14 21:06 * @desc 字段非null校验 */ @Target(value = {ElementType.FIELD,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface NotNull { ServiceTypeEnum[] type() default {ServiceTypeEnum.ALL}; /** * 参数名 * @return */ String name() default ""; /** * 报错信息 * @return */ String msg() default "不能为空"; } /** * @author LiuHuan * @date 2019-11-14 21:06 * @desc bean校验 */ @Target(value = {ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface VerifyBean { /** * 校验类型 * @return */ ServiceTypeEnum type() default ServiceTypeEnum.ALL; /** * 参数名 * @return */ String name(); /** * 报错信息 * @return */ String msg() default "不能为空"; }
5、枚举
/** * @author LiuHuan * @date 2019-11-14 21:52 * @desc 请求类型枚举 */ public enum ServiceTypeEnum { /** * 所有 */ ALL, /** * 新增 */ INSERT, /** * 删除 */ DELETE, /** * 修改 */ UPDATE }
6、异常
/** * @author LiuHuan * @date 2019-11-15 10:03 * @desc 参数异常 */ public class ParamException extends RuntimeException{ private List<String> errorList; public ParamException(List<String> errorList) { this.errorList = errorList; } public List<String> getErrorList() { return errorList; } public void setErrorList(List<String> errorList) { this.errorList = errorList; } @Override public String getMessage() { return errorList.toString(); } }