ITPub博客

首页 > > > Springboot项目的接口防刷(实例)

Springboot项目的接口防刷(实例)

作者:xiaojun63 时间:2019-12-11 13:53:07 0 删除 编辑

来源:https://urlify.cn/ERf6Rr

说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考。

技术要点:springboot的基本知识,redis基本操作,

首先是写一个注解类:

import java.lang.annotation.Retention;

import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**

* @author yhq

* @date 2018/9/10 15:52

*/

@Retention(RUNTIME)

@Target(METHOD)

public @interface AccessLimit {

int seconds();

int maxCount();

boolean needLogin()default true;

}

接着就是在Interceptor拦截器中实现:

import com.alibaba.fastjson.JSON;

import com.example.demo.action.AccessLimit;

import com.example.demo.redis.RedisService;

import com.example.demo.result.CodeMsg;

import com.example.demo.result.Result;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.OutputStream;

/**

* @author yhq

* @date 2018/9/10 16:05

*/

@Component

public class FangshuaInterceptor extends HandlerInterceptorAdapter {

@Autowired

private RedisService redisService;

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//判断请求是否属于方法的请求

if(handler instanceof HandlerMethod){

HandlerMethod hm = (HandlerMethod) handler;

//获取方法中的注解,看是否有该注解

AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);

if(accessLimit == null){

return true;

}

int seconds = accessLimit.seconds();

int maxCount = accessLimit.maxCount();

boolean login = accessLimit.needLogin();

String key = request.getRequestURI();

//如果需要登录

if(login){

//获取登录的session进行判断

//.....

key+=""+"1"; //这里假设用户是1,项目中是动态获取的userId

}

//从redis中获取用户访问的次数

AccessKey ak = AccessKey.withExpire(seconds);

Integer count = redisService.get(ak,key,Integer.class);

if(count == null){

//第一次访问

redisService.set(ak,key,1);

}else if(count < maxCount){

//加1

redisService.incr(ak,key);

}else{

//超出访问次数

render(response,CodeMsg.ACCESS_LIMIT_REACHED); //这里的CodeMsg是一个返回参数

return false;

}

}

return true;

}

private void render(HttpServletResponse response, CodeMsg cm)throws Exception {

response.setContentType("application/json;charset=UTF-8");

OutputStream out = response.getOutputStream();

String str = JSON.toJSONString(Result.error(cm));

out.write(str.getBytes("UTF-8"));

out.flush();

out.close();

}

}

再把Interceptor注册到springboot中

import com.example.demo.ExceptionHander.FangshuaInterceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**

* @author yhq

* @date 2018/9/10 15:58

*/

@Configuration

public class WebConfig extends WebMvcConfigurerAdapter {

@Autowired

private FangshuaInterceptor interceptor;

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(interceptor);

}

}

接着在Controller中加入注解

import com.example.demo.result.Result;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

/**

* @author yhq

* @date 2018/9/10 15:49

*/

@Controller

public class FangshuaController {

@AccessLimit(seconds=5, maxCount=5, needLogin=true)

@RequestMapping("/fangshua")

@ResponseBody

public Result fangshua(){

return Result.success("请求成功");

}

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/658/viewspace-3150241/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-04-12

  • 博文量
    243
  • 访问量
    3055