java注解-验签、日志、拦截(切面)

1、创建注解、添加属性。

例:接口访问时间段限制

复制代码
package com.yhsp.payapi.aspect;

import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * @author guocz
 * @date 20211129
 * 接口访问时间限制
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessTime {

    String message() default "当前时间不允许访问";

    /**
     * 数据字典key(每一天:HH:mm:ss)
     */
    String bizKey() default "";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}
复制代码

2、创建注解实现类,采用切面。

使用切点@Pointcut("@annotation(com.yhsp.payapi.aspect.AccessTime)")绑定注解类。

使用@Before("pointcut() && @annotation(accessTime)")确定切入点为访问接口前。

并使用@annotation(accessTime)传递注解属性。

复制代码
package com.yhsp.payapi.aspect.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.yhsp.pay.common.exception.CustomException;
import com.yhsp.pay.common.result.pay.ApiCode;
import com.yhsp.pay.common.result.pay.ApiSubCode;
import com.yhsp.pay.core.utils.DictionaryUtil;
import com.yhsp.payapi.aspect.AccessTime;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author guocz
 * @date 20211129
 * 接口访问时间限制
 */
@Aspect
@Component
@Log4j2
public class AccessTimeValidator {

    @Pointcut("@annotation(com.yhsp.payapi.aspect.AccessTime)")
    private void pointcut() {

    }

    @Before("pointcut() && @annotation(accessTime)")
    public void before(AccessTime accessTime) {
        String bizKey = accessTime.bizKey();
        if (StringUtils.isBlank(bizKey)) {
            return;
        }

        // 获取数据字典值
        String timeString = DictionaryUtil.fetchData(bizKey, String.class);
        if (StringUtils.isBlank(timeString)) {
            log.error("key为" + bizKey + "的数据字典未配置");
            throw new CustomException(ApiCode.BIZ_FAIL, ApiSubCode.BIZ_FAIL_DICTIONARY_NOT_EXIST);
        }
        String[] strings = timeString.split(",");
        LocalDateTime now = LocalDateTime.now();
        String ymd = LocalDateTimeUtil.format(now, "yyyy-MM-dd");
        // 起始时间(HH:mm:ss)
        LocalDateTime timeBegin;
        // 终止时间(HH:mm:ss)
        LocalDateTime timeEnd;
        try {
            timeBegin = LocalDateTimeUtil.parse(ymd + " " + strings[0], "yyyy-MM-dd HH:mm:ss");
            timeEnd = LocalDateTimeUtil.parse(ymd + " " + strings[1], "yyyy-MM-dd HH:mm:ss");
        }catch (Exception e) {
            log.error("key为" + bizKey + "的时间格式配置有误");
            throw new CustomException(ApiCode.BIZ_FAIL, ApiSubCode.ERROR_CONFIG_ERROR);
        }
        if (now.isBefore(timeBegin) || now.isAfter(timeEnd)) {
            log.warn("key为" + bizKey + "当前时间不允许访问");
            throw new CustomException(ApiCode.ERROR, ApiSubCode.ERROR_ACCESS_ERROR, accessTime.message());
        }
    }

}
复制代码

3、如果需要获取入参等信息,可在切面方法中添加JoinPoint参数。

JoinPoint使用方法可参考https://blog.csdn.net/qq_15037231/article/details/80624064

复制代码
package com.yhsp.payapi.aspect;

import com.yhsp.pay.common.utils.AspectUtil;
import com.yhsp.pay.gateway.utils.OpenApiSignUtil;
import com.yhsp.pay.model.param.OpenApiBaseParam;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class OpenApiSignVerifyAspect {

    @Autowired
    private OpenApiSignUtil openApiSignUtil;

    @Autowired
    private AspectUtil aspectUtil;

    @Pointcut("@annotation(com.yhsp.payapi.aspect.OpenApiSignVerify)")
    private void pointcut() {
    }

    @Before("pointcut() && @annotation(signVerify)")
    public void before(JoinPoint joinPoint, OpenApiSignVerify signVerify) {
        OpenApiBaseParam param = (OpenApiBaseParam) aspectUtil.getFieldsName(joinPoint).get("param");
        openApiSignUtil.verifySign(param);
    }

}
复制代码

 

posted @   幻影黑子  阅读(1103)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示