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); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)