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. 简单的股票信息查询系统 1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环) 2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来 3 允许按股票价格、涨跌幅、换手率这几列来筛选信息, 比如输入“价格>50”则把价格大于50的股票都打印,输入“市盈率<50“,则把市盈率小于50的股票都打印,不用判断等于。

    '''需求:1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环)2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来3 允许按股票价格 ...

  2. MAC安装Navicat Premiun12

    链接地址:https://blog.csdn.net/wenyicodedog/article/details/97970154

  3. 吊打 Tomcat ,Undertow 性能很炸!!

    在 Java Web 容器的世界里,Tomcat 和 Jetty 是大名鼎鼎的.用的最多的开源项目,也是大众熟知的. 今天再介绍另外一款能和 Tomcat 媲美的神器:Undertow,据说性能方面还 ...

  4. Spring Cloud--尚硅谷2020最新版

    Spring Cloud 初识Spring Cloud与微服务 在传统的软件架构中,我们通常采用的是单体应用来构建一个系统,一个单体应用糅合了各种业务模块.起初在业务规模不是很大的情况下,对于单体应用 ...

  5. react项目初始化配置

    ## [初始化项目](https://facebook.github.io/create-react-app/)) + 安装 ``` npx create-react-app myreact ``` ...

  6. source insight编辑matlab,不可

    先说结论,我用的source insight版本是4.0x,matlab的语言包用的sourceinght官网提供的matlab.clf.链接如下:https://www.sourceinsight. ...

  7. Java面试题 200+

    面试题包含的内容了十九了模块:Java 基础.容器.多线程.反射.对象拷贝.Java Web 模块.异常.网络.设计模式.Spring/Spring MVC.Spring Boot/Spring Cl ...

  8. efcore技巧贴-也许有你不知道的使用技巧

    前言 .net 环境近些年也算是稳步发展.在开发的过程中,与数据库打交道是必不可少的.早期的开发者都是DbHelper一撸到底,到现在的各种各样的ORM框架大行其道.孰优孰劣谁也说不清楚,文无第一武无 ...

  9. 深入探究.Net Core Configuration读取配置的优先级

    前言     在之前的文章.Net Core Configuration源码探究一文中我们曾解读过Configuration的工作原理,也.Net Core Configuration Etcd数据源 ...

  10. java基础(swing+jsp+mybatis配置)

    JAVA SE GUI编程(swing) # 组件 描述 1 JFrame 一个普通的窗口(绝大多数 Swing 图形界面程序使用 JFrame 作为顶层容器) 2 JDialog 对话框 常用的中间 ...