(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工具校验时间格式。

效果

579

附:解析获取请求参数的方法

/**
     * 获取参数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),请求参数结构不同。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐