Pour l'instant, je pense qu'il y a beaucoup de cas d'utilisation de l'interface API. Cependant, si l'API est appelée trop de fois, le traitement côté serveur peut être retardé. Cela signifie que quelque chose de mauvais va se passer. Cette fois, afin de limiter le nombre d'accès à l'API, j'ai écrit cet article après un examen et une réflexion approfondis.
Vous devez avoir à la fois des connaissances Spring Boot et des connaissances Redis.
En tant que politique de mise en œuvre, elle est implémentée sous forme d'annotation principalement à l'aide de Spring Boot et Redis. Vous pouvez voir les détails en regardant le commentaire.
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 {
//Limite de temps(Secondes)
int seconds();
//Nombre maximum d'accès
int maxCount();
//Statut de connexion
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 {
//Découvrez si la requête est une HandlerMethod
if(handler instanceof HandlerMethod){
HandlerMethod hm = (HandlerMethod) handler;
//Obtenez l'annotation au-dessus de la méthode et voyez s'il existe une annotation AccessLimit
AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
if(accessLimit == null){
//Ne rien faire sans l'annotation AccessLimit
return true;
}
//Obtenez la limite de temps
int seconds = accessLimit.seconds();
//Obtenez le nombre maximum d'accès
int maxCount = accessLimit.maxCount();
boolean login = accessLimit.needLogin();
String key = request.getRequestURI();
//Si une connexion est requise, procédez comme suit:
if(login){
//Je vais omettre la partie authentification ici
// key+=""+"userInfo";
}
//Obtenez le nombre d'accès de Redis
AccessKey ak = AccessKey.withExpire(seconds);
Integer count = redisService.get(ak,key,Integer.class);
//Créez une branche et effectuez chaque processus
if(count == null){
//Lors de l'accès pour la première fois
redisService.set(ak,key,1);
}else if(count < maxCount){
//Nombre d'accès + 1
redisService.incr(ak,key);
}else{
//Si le nombre maximum d'accès est dépassé, un message d'erreur sera créé et renvoyé.
render(response,"Le nombre maximum d'accès sera dépassé dans le délai spécifié."); //
return false;
}
}
return true;
}
/**
*Si le nombre maximum d'accès est dépassé, un message d'erreur sera créé et renvoyé.
*/
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();
}
}
Enregistrez la classe d'intercepteur créée dans 2 ci-dessus dans 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);
}
}
J'ai créé un contrôleur et mis @AccessLimit au-dessus de la méthode. Une fois que c'est fait, testons avec 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 {
//Temps: 5 secondes,Nombre maximum d'accès:5 ,Statut de connexion: obligatoire
@AccessLimit(seconds=5, maxCount=5, needLogin=true)
@RequestMapping("/ApiLimitTest")
@ResponseBody
public Result<String> ApiLimitTest(){
return Result.success("Demande réussie!");
}
}
Merci d'avoir lu jusqu'au bout. N'hésitez pas à signaler les parties qui vous semblent étranges. Je vous remercie.