package com.lanfu.storehouse.annotation;
//先自定义一个注解 import java.lang.annotation.*; @Inherited @Documented @Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface AccessLimit { //标识 指定sec时间段内的访问次数限制 int limit() default 5; //标识 时间段 int sec() default 5; }
写一个切面
package com.lanfu.storehouse.aspect; import com.lanfu.storehouse.annotation.AccessLimit; import com.lanfu.storehouse.common.base.ErrorCodeEnum; import com.lanfu.storehouse.common.exception.BaseBussinessException; import com.lanfu.storehouse.common.util.IpAddressUtil; import com.lanfu.storehouse.common.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; @Aspect @Component @Slf4j public class AccessLimitAspectAdvice { @Pointcut("@annotation(com.lanfu.storehouse.annotation.AccessLimit)") private void entryPoint(){ } @Around("entryPoint()&& @annotation(accessLimit)") public Object accessLimit(ProceedingJoinPoint joinPoint, AccessLimit accessLimit) throws Throwable { //获取HttpServletRequest RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; HttpServletRequest request = servletRequestAttributes.getRequest(); //获取注解中的参数 int limit = accessLimit.limit(); int sec = accessLimit.sec(); //使用ip加接口作为key存到redis中 String key = IpAddressUtil.getIpAddr(request) + request.getRequestURI(); Integer maxLimit = (Integer) RedisUtil.get(key); if (maxLimit == null) { //set时一定要加过期时间 RedisUtil.set(key, 1, sec); } else if (maxLimit < limit) { RedisUtil.set(key, maxLimit + 1, sec); } else { throw new BaseBussinessException(ErrorCodeEnum.GW10019013); } System.out.println("joinPoint = " + joinPoint.toString()); System.out.println("joinPoint = " + joinPoint.proceed().toString()); return joinPoint.proceed(); } }
使用
@RequestMapping(method = RequestMethod.POST, value = "/apiCallBack") @ResponseBody @AccessLimit(limit = 10,sec = 5) public BaseResult apiCallBack(@RequestBody Map map, HttpServletRequest httpServletRequest){ System.out.println(map.toString()); // String appId = requestMessageVo.getAppId(); // String content = requestMessageVo.getContent(); // Long timestamp = requestMessageVo.getTimestamp(); // String concatString = appId+"507f513353702b50c145d5b7d138095c"+content+timestamp; // String sign = requestMessageVo.getSign(); // String md5String = MD5Util.md5(concatString); // if (!md5String.equals(sign)){ // throw new BaseBussinessException(ErrorCodeEnum.GW10019002); // } // System.out.println("===回调参数==="+content); return BaseResult.error(); }
//打印出来的东西。
joinPoint = execution(BaseResult com.lanfu.storehouse.controller.GuCangAPIController.apiCallBack(Map,HttpServletRequest))
joinPoint = com.lanfu.storehouse.common.base.BaseResult@39924a6f