使用注解怎么实现一个springboot 接口防刷功能-mile米乐体育
行业资讯
2021年03月02日 23:49
2
这篇文章将为大家详细讲解有关使用注解怎么实现一个springboot 接口防刷功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
项目结构如下:
一、编写注解类 accesslimit
packagecn.mygweb.annotation; importjava.lang.annotation.elementtype; importjava.lang.annotation.retention; importjava.lang.annotation.retentionpolicy; importjava.lang.annotation.target; /** *访问控制注解(实现接口防刷功能) */ @retention(retentionpolicy.runtime) @target(elementtype.method) public@interfaceaccesslimit{ /** *限制周期(单位为秒) * *@return */ intseconds(); /** *规定周期内限制次数 * *@return */ intmaxcount(); /** *是否需要登录 * *@return */ booleanneedlogin()defaultfalse; }
二、在interceptor拦截器中实现拦截逻辑
packagecn.mygweb.interceptor; importcn.mygweb.annotation.accesslimit; importcn.mygweb.entity.result; importcn.mygweb.entity.statuscode; importcom.alibaba.fastjson.json; importorg.springframework.stereotype.component; importorg.springframework.web.method.handlermethod; importorg.springframework.web.servlet.handler.handlerinterceptoradapter; importjavax.servlet.http.httpservletrequest; importjavax.servlet.http.httpservletresponse; importjava.io.outputstream; importjava.util.hashmap; importjava.util.map; /** *访问控制拦截器 */ @component publicclassaccesslimitinterceptorextendshandlerinterceptoradapter{ //模拟数据存储,实际业务中可以自定义实现方式 privatestaticmapaccessinfomap=newhashmap<>(); @override publicbooleanprehandle(httpservletrequestrequest,httpservletresponseresponse, objecthandler)throwsexception{ //判断请求是否属于方法的请求 if(handlerinstanceofhandlermethod){ handlermethodhm=(handlermethod)handler; //获取方法中的注解,看是否有该注解 accesslimitaccesslimit=hm.getmethodannotation(accesslimit.class); if(accesslimit==null){ returntrue; } intseconds=accesslimit.seconds(); intmaxcount=accesslimit.maxcount(); booleanneedlogin=accesslimit.needlogin(); stringkey=request.getrequesturi(); //如果需要登录 if(needlogin){ //获取登录的session进行判断 //…… key ="" "usera";//这里假设用户是usera,实际项目中可以改为userid } //模拟从redis中获取数据 accessinfoaccessinfo=accessinfomap.get(key); if(accessinfo==null){ //第一次访问 accessinfo=newaccessinfo(); accessinfo.setfirstvisittimestamp(system.currenttimemillis()); accessinfo.setaccesscount(1); accessinfomap.put(key,accessinfo); }elseif(accessinfo.getaccesscount() 三、把interceptor注册到springboot中
packagecn.mygweb.config; importcn.mygweb.interceptor.accesslimitinterceptor; importorg.springframework.context.annotation.configuration; importorg.springframework.web.servlet.config.annotation.interceptorregistry; importorg.springframework.web.servlet.config.annotation.webmvcconfigurer; /** *拦截器注册配置 */ @configuration publicclasswebconfigimplementswebmvcconfigurer{ @override publicvoidaddinterceptors(interceptorregistryregistry){ //注册拦截器 registry.addinterceptor(newaccesslimitinterceptor()); } }四、在controller中加入注解实现接口防刷
packagecn.mygweb.controller; importcn.mygweb.annotation.accesslimit; importcn.mygweb.entity.result; importcn.mygweb.entity.statuscode; importorg.springframework.web.bind.annotation.getmapping; importorg.springframework.web.bind.annotation.requestmapping; importorg.springframework.web.bind.annotation.restcontroller; @restcontroller @requestmapping(" access")="" publicclassaccesscontroller{="" @accesslimit(seconds="5,maxcount=2)//访问控制,5秒内只能访问2次" @getmapping="" publicresultaccess(){="" returnnewresult(true,statuscode.ok,"访问成功!");="" }<="" pre="">五、测试访问
附:statuscode.java、result.java、application.yml
statuscode类
packagecn.mygweb.entity; /** *返回状态码 */ publicclassstatuscode{ publicstaticfinalintok=20000;//成功 publicstaticfinalinterror=20001;//失败 publicstaticfinalintloginerror=20002;//用户名或密码错误 publicstaticfinalintaccesserror=20003;//权限不足 publicstaticfinalintremoteerror=20004;//远程调用失败 publicstaticfinalintreperror=20005;//重复操作 publicstaticfinalintnotfounderror=20006;//没有对应的抢购数据 }result类:
packagecn.mygweb.entity; importjava.io.serializable; /** *响应结果 */ publicclassresultimplementsserializable{ privatebooleanflag;//是否成功 privateintegercode;//返回码 privatestringmessage;//返回消息 privatetdata;//返回数据 publicresult(booleanflag,integercode,stringmessage,objectdata){ this.flag=flag; this.code=code; this.message=message; this.data=(t)data; } publicresult(booleanflag,integercode,stringmessage){ this.flag=flag; this.code=code; this.message=message; } publicresult(){ this.flag=true; this.code=statuscode.ok; this.message="操作成功!"; } publicbooleanisflag(){ returnflag; } publicvoidsetflag(booleanflag){ this.flag=flag; } publicintegergetcode(){ returncode; } publicvoidsetcode(integercode){ this.code=code; } publicstringgetmessage(){ returnmessage; } publicvoidsetmessage(stringmessage){ this.message=message; } publictgetdata(){ returndata; } publicvoidsetdata(tdata){ this.data=data; } } applications.yml:
server: port:8080关于使用注解怎么实现一个springboot 接口防刷功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
展开全文