(1条消息) SpringBoot实践之(十四)— AOP拦截器 Aspect的使用_luckykapok918的博客-CSDN博客
Spring Boot使用AOP的正确姿势 - James_Shangguan - 博客园 (cnblogs.com)
对于权限的校验以及时间格式的校验确实使用spring aop处理会比较方便。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
定义用于拦截的controller
@RestController
@Slf4j
public class Controller {
@PostMapping("/add")
@ApiOperation(value = "新增")
@ScheduleTimeVerifyTag
public AjaxResult<Boolean> add(@RequestBody @Validated ShopReq req) {
return shopService.add(req);
}
}
定义时间校验Tag
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ScheduleTimeVerifyTag {
}
定义切面
@Component
@Aspect
@Slf4j
public class TimeVerifyAspect {
@Before("@annotation(com.xxx.annotation.ScheduleTimeVerifyTag)")
public void before(JoinPoint joinPoint) {
List<String> list = Arrays.asList("businessStart","businessEnd","restTime1", "restTime2","latestWork","workingTimeStart","workingTimeEnd");
//参数值
Object[] paramValues = joinPoint.getArgs();
for (String each : list) {
//如果参数不存在
if (Objects.isNull(ReflectUtil.getFieldValue(paramValues[0], each))) {
log.warn("【参数{}不存在】", each);
continue;
}
String fieldValue = ReflectUtil.getFieldValue(paramValues[0], each).toString();
//如果参数值存在
if (!StringUtils.isEmpty(fieldValue)) {
String[] split1 = fieldValue.split("-");
for (String s : split1) {
verify(each, s);
}
}
}
}
/**
* 校验时间格式
*
* @param field 字段名
* @param time 时间
*/
private void verify(String field, String time) {
try {
DateUtil.parse(time, "HH:mm:ss");
} catch (Exception e) {
log.warn("【{}时间{}格式校验失败】", field, time);
throw new ServiceException(Constants.SERVER_ERROR, ErrorConstants.INVALID_TIME);
}
}
}
切点主要设置的是 Tag的相对路径,也可以使用 execution(具体可参考:Spring Boot使用AOP的正确姿势 - James_Shangguan - 博客园 (cnblogs.com))。不过我觉得加 tag会方便许多。
这个页面主要是拦截请求入参,获取相关的时间字段是否符合(HH:mm:ss) 格式,如果不符合则提示用户。这里使用到Hutool提供的反射工具类(ReflectUtil)获取请求对象的属性值,然后也是使用其DateUtil工具校验时间格式。
效果
附:解析获取请求参数的方法
/**
* 获取参数map
*
* @param joinPoint
* @return
*/
private Map<String, Object> getParamMap(JoinPoint joinPoint) {
Map<String, Object> params = new HashMap<>();
Object[] paramValues = joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for (int i = 0; i < paramNames.length; i++) {
params.put(paramNames[i], paramValues[i]);
}
return params;
}
这里需要考虑不同的请求方式(GET POST),请求参数结构不同。