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. python 基础-文件读写'r' 和 'rb'区别

    原文链接: python基础-文件读写'r' 和 'rb'区别 一.Python文件读写的几种模式: r,rb,w,wb 那么在读写文件时,有无b标识的的主要区别在哪里呢? 1.文件使用方式标识 'r ...

  2. 2020.5.22 第二篇 Scrum冲刺博客

    Team:银河超级无敌舰队 Project:招新通 项目冲刺集合贴:链接 目录 一.每日站立会议 二.项目燃尽图 三.签入记录 3.1 代码/文档签入记录 3.2 主要代码截图 3.3 程序运行截图 ...

  3. SPSSAU数据分析思维培养系列2:分析方法

    大家好!在上篇文章中,我们一起学习了如何掌握正确的数据处理思维(文章链接:https://www.cnblogs.com/spssau/p/12523530.html).在完成数据准备和清理工作后,就 ...

  4. 使用VS开发的一个开机自启动启动、可接收指定数据关闭电脑或打开其他程序

    使用VS开发的一个开机自启动启动.可接收指定数据关闭电脑或打开其他程序需要注意的几点 为了能够在其他电脑上运行自己写的程序,需要在VS改一下编译的运行库.(项目->属性->配置属性-> ...

  5. Excel—TIME函数简介与用法

    问题场景 算员工饱和度时,需要从实际考勤打卡时间中减去午休时间1.5个小时: 导出的时间时分秒是分开的,连接时分秒. 场景一 计算员工饱和度,需要减去午休时间,用下班打卡时间减去午休的1.5小时算出的 ...

  6. 使用 Postman 做 API 自动化测试

    Postman 最基本的功能用来重放请求,并且配合良好的 response 格式化工具. 高级点的用法可以使用 Postman 生成各个语言的脚本,还可以抓包,认证,传输文件. 仅仅做到这些还不能够满 ...

  7. java调用C# webService发布的接口

    java调用C# webService发布的接口 java调用C# webService方式有很多种我这里只介绍一种 首先需要引入axis的jar包 axis的maven坐标如下 <depend ...

  8. linux系统指法练习与打字游戏软件

    以 fedora和ubuntu 系统为例,fedora/centos系统用yum install命令安装 ubuntu系统用apt-get instll命令安装 yum install ktouch$ ...

  9. js中的各种常用方法(持续更新中。。。)

    我看到常用的就写上去,如果你们有,可以在评论上发表,我再把它补充到我的随笔中 some() var ages = [3, 10, 18, 20]; function checkAdult(age) { ...

  10. 基于python tkinter的课堂点名小程序

    import datetime import json import os import random import tkinter as tk import openpyxl # 花名册文件名很多人 ...