Im Moment denke ich, dass es viele Fälle gibt, in denen die API-Schnittstelle verwendet wird. Wenn Sie die API jedoch zu oft aufrufen, kann sich die serverseitige Verarbeitung verzögern. Es bedeutet, dass etwas Schlimmes passieren wird. Dieses Mal habe ich diesen Artikel nach sorgfältiger Prüfung und Überlegung geschrieben, um die Anzahl der Zugriffe auf die API zu begrenzen.
Sie müssen sowohl Spring Boot- als auch Redis-Kenntnisse haben.
Als Implementierungsrichtlinie wird sie in Form von Anmerkungen hauptsächlich mithilfe von Spring Boot und Redis implementiert. Sie können die Details sehen, indem Sie sich den Kommentar ansehen.
AccessLimit.java
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 Hyman
* @date 2019/12/25 11:12
*/
@Retention(RUNTIME)
@Target(METHOD)
public @interface AccessLimit {
//Zeitlimit(Sekunden)
int seconds();
//Maximale Anzahl von Zugriffen
int maxCount();
//Anmeldestatus
boolean needLogin() default true;
}
ApiLimitInterceptor.java
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 Hyman
* @date 2019/12/25 11:22
*/
@Component
public class ApiLimitInterceptor extends HandlerInterceptorAdapter {
@Autowired
private RedisService redisService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//Finden Sie heraus, ob es sich bei der Anforderung um eine HandlerMethod handelt
if(handler instanceof HandlerMethod){
HandlerMethod hm = (HandlerMethod) handler;
//Rufen Sie die Annotation über der Methode ab und prüfen Sie, ob eine AccessLimit-Annotation vorhanden ist
AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
if(accessLimit == null){
//Machen Sie nichts ohne die AccessLimit-Annotation
return true;
}
//Holen Sie sich das Zeitlimit
int seconds = accessLimit.seconds();
//Holen Sie sich die maximale Anzahl von Zugriffen
int maxCount = accessLimit.maxCount();
boolean login = accessLimit.needLogin();
String key = request.getRequestURI();
//Wenn eine Anmeldung erforderlich ist, gehen Sie wie folgt vor:
if(login){
//Ich werde den Authentifizierungsteil hier weglassen
// key+=""+"userInfo";
}
//Holen Sie sich die Anzahl der Zugriffe von redis
AccessKey ak = AccessKey.withExpire(seconds);
Integer count = redisService.get(ak,key,Integer.class);
//Erstellen Sie eine Verzweigung und führen Sie jeden Prozess aus
if(count == null){
//Beim ersten Zugriff
redisService.set(ak,key,1);
}else if(count < maxCount){
//Zugriffsanzahl + 1
redisService.incr(ak,key);
}else{
//Wenn die maximale Anzahl von Zugriffen überschritten wird, wird eine Fehlermeldung erstellt und zurückgegeben.
render(response,"Die maximale Anzahl von Zugriffen wird innerhalb der angegebenen Zeit überschritten."); //
return false;
}
}
return true;
}
/**
*Wenn die maximale Anzahl von Zugriffen überschritten wird, wird eine Fehlermeldung erstellt und zurückgegeben.
*/
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();
}
}
Registrieren Sie die in 2 oben erstellte Interceptor-Klasse in Spring Boot.
WebConfig.java
import com.example.demo.ExceptionHander.ApiLimitInterceptor;
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 Hyman
* @date 2019/11/31 15:58
*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private ApiLimitInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor);
}
}
Ich habe einen Controller erstellt und @AccessLimit über die Methode gesetzt. Sobald dies erledigt ist, testen wir mit Postman.
ApiLimitController.java
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 Hyman
* @date 2019/12/25 13:21
*/
@Controller
public class ApiLimitController {
//Zeit: 5 Sekunden,Maximale Anzahl von Zugriffen:5 ,Anmeldestatus: Erforderlich
@AccessLimit(seconds=5, maxCount=5, needLogin=true)
@RequestMapping("/ApiLimitTest")
@ResponseBody
public Result<String> ApiLimitTest(){
return Result.success("Erfolgreiche Anfrage!");
}
}
Vielen Dank für das Lesen bis zum Ende. Bitte zögern Sie nicht, auf Teile hinzuweisen, die Sie für seltsam halten. Vielen Dank.
Recommended Posts