controller:
@Delay(time = 2) <--重点是这个注解
@ApiOperation("用户换书开格子")
@PostMapping("/user/inbooks/open/grid")
public ResultData inbooksOpenGrid(@RequestBody InBookVO inBookVO) throws Exception {
return zkService.inbooksOpenGrid(inBookVO);
}
自定义注解类
/**
* 默认时长为秒单位
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Delay {
int time() default 1;
}
一定要有个拦截器进行拦截
@Configuration
public class HeaderTokenInterceptor extends WebMvcConfigurerAdapter {
@Bean
public AdminSecurityInterceptor adminSecurityInterceptor(){
return new AdminSecurityInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration adminInterceptor = registry.addInterceptor(adminSecurityInterceptor());
// 不拦截
adminInterceptor.excludePathPatterns("/admin/login")
.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
//拦截所有路径
adminInterceptor.addPathPatterns("/admin111/**","/zk/user/inbooks/open/grid","/zk/user/inbooks","/zk/user/inbooks/byphone","/zk/cabinet/user/bookcode",
"/zk/user/return/grid/books/new","/zk/user/returnbooks/books/new","/zk/user/borrowbooks2","/zk/regular/disinfection","/zk/user/return/grid/books",
"/zk/user/returnbooks/books/");
}
}
重点是拦截后的处理
public class AdminSecurityInterceptor extends HandlerInterceptorAdapter {
/**
* logger instance
*/
static Logger logger = LoggerFactory.getLogger(AdminSecurityInterceptor.class);
private long lastTime = 0;
@Autowired
private RedisUtil redisUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
String url = request.getRequestURI();
logger.info("请求路径:" + url);
String ipAddr = GetIp.getIpAddr(request);
logger.info("IP地址:" + ipAddr);
logger.info("handler:" + handler);
String biaoshi = ipAddr+url;
//开始进入请求地址拦截
HandlerMethod hm = (HandlerMethod) handler;
Delay delay = hm.getMethodAnnotation(Delay.class);
if (delay != null) {
boolean b = redisiscunzai(biaoshi,delay.time());
if(b==false){
JSONObject res = new JSONObject();
res.put("data", new ArrayList<>());
res.put("msg", "请勿重复请求");
res.put("code", 2);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
out = response.getWriter();
out.append(res.toString());
return false;
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//处理请求完成后视图渲染之前的处理操作
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//视图渲染之后的操作
}
private boolean startDelay(int time) { //此方法为本地缓存不适用 参数time 为毫秒
long currentTime = System.currentTimeMillis();
if (currentTime - lastTime > time) {
lastTime = currentTime;
return true;
}
return false;
}
private boolean redisiscunzai(String value,int time) {//此方法为本次演示 参数time 为秒
//如果缓存中没有返回true
boolean b = redisUtil.selectKeyIsOk(value);
if (!b) {//没有返回通过
redisUtil.set(value, 1, time);
return true;
}
return false;
}
}
此方法适用于拦截IP对某路径的访问限制,存储到redis中,在redis中存储时长默认为1秒,在controller上的注释可自定义,
代码运行中如遇到 redis 为null 请参考 本文中的‘HeaderTokenInterceptor’ 方法
本文原创,小白一枚,大神请指点,不喜勿喷