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();
}
}

AOP参数校验的更多相关文章

  1. springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验--异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档---jpa访问数据库及page进行分页---整合redis---定时任务

    springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验-- 异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档 ...

  2. springmvc 参数校验/aop失效/@PathVariable 参数为空

    添加依赖 <!-- 参数校验 --> <dependency> <groupId>org.hibernate.validator</groupId> & ...

  3. springboot+aop+自定义注解,打造通用的全局异常处理和参数校验切面(通用版)

    一.引入相应的maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifa ...

  4. 利用Aspectj实现Oval的自动参数校验

    前言: Oval参数校验框架确实小巧而强大, 他通过注解的方式配置类属性, 然后通过Oval本身自带的工具类, 快速便捷执行参数校验. 但是工具类的校验需要额外的代码编写, 同时Oval对函数参数级的 ...

  5. springboot 参数校验详解

    https://www.jianshu.com/p/89a675b7c900 在日常开发写rest接口时,接口参数校验这一部分是必须的,但是如果全部用代码去做,显得十分麻烦,spring也提供了这部分 ...

  6. SpringBoot 参数校验的方法

    Introduction 有参数传递的地方都少不了参数校验.在web开发中,前端的参数校验是为了用户体验,后端的参数校验是为了安全.试想一下,如果在controller层中没有经过任何校验的参数通过s ...

  7. Spring Boot 之:接口参数校验

    Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ...

  8. Spring Boot实现通用的接口参数校验

    Spring Boot实现通用的接口参数校验 Harries Blog™ 2018-05-10 2418 阅读 http ACE Spring App API https AOP apache IDE ...

  9. SpringMVC参数校验,包括JavaBean和基本类型的校验

    该示例项目使用SpringBoot,添加web和aop依赖. SpringMVC最常用的校验是对一个javaBean的校验,默认使用hibernate-validator校验框架.而网上对校验单个参数 ...

随机推荐

  1. Vector-based navigation using grid-like representations in artificial agents

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Nature May 17, 2018 Received: 5 July 2017; Accepted: 3 April 2018;Pub ...

  2. C# DataTable查询示例

    代码 public void Test() { #region 初始化数据 /* 数据 张三 语文 34.00 张三 数学 58.00 张三 英语 61.00 李四 语文 45.00 李四 数学 87 ...

  3. 什么是PR劫持和权重劫持

    http://www.wocaoseo.com/thread-265-1-1.html PR劫持OR网站权重劫持虽然概念不一样,但是其原理是一样的,同样属于seo中的灰色手段,是我们抵制和反对的seo ...

  4. 前端ES6 一些面试题

    1.ES5.ES6和ES2015有什么区别? ES2015特指在2015年发布的新一代JS语言标准,ES6泛指下一代JS语言标准,包含ES2015.ES2016.ES2017.ES2018等.现阶段在 ...

  5. oracle备份之备份测试脚本(冷备、热备、rman)

    1.数据库环境 数据库DBID及打开模式SQL> select dbid,open_mode from v$database; DBID OPEN_MODE---------- -------- ...

  6. 【免费】windows下如何生成tar.gz,一键生成tar.gz

    废话 一.实验背景 tar.gz 是Linux和Unix下面比较常用的格式,一条命令就可以把文件压缩打包成tar.gz格式,然而这种格式在windows并不多见. Linxu服务器上,tar.gz 包 ...

  7. ES6--let,解构赋值,promise && ES7--async

    ES-->IE10.Google.火狐 ES6 let 声明的关键字 不能重复声明 块级作用域 <input type="button" value="1&q ...

  8. Python の 在 VSCode 中使用 IPython Kernel 的方法

    本文介绍,在 VSCode 使用 IPython Kernel,的设置方法. 要达到的效果: 只需按下 Ctrl+:,选中的几行代码,就会自动发送到 IPython Kernel,并运行,得到结果!当 ...

  9. 分享一款知识库平台系统-wcp

    入园这么些天了,今天搭建了一套知识库系统,使用效果还不错,分享一些过程经验. 搭建准备: 软件系统:WCP4.3免费版 (免费开源,支持Windows,使用简单,有傻瓜式一键安装包-win平台) 服务 ...

  10. WEBAPI 增加身份验证

    1,在Webapi项目下添加如下引用: Microsoft.AspNet.WebApi.Owin Owin Microsoft.Owin.Host.SystemWeb Microsoft.Owin.S ...