精华内容
下载资源
问答
  • 限制接口或方法的执行时间 java

    千次阅读 2018-06-14 10:57:26
    //限制接口或方法执行时间 ExecutorService exec = Executors.newFixedThreadPool(1); Callable<String> call = new Callable<String>() { public String call() throws Exception {//...
    //限制接口或方法执行时间
    ExecutorService exec = Executors.newFixedThreadPool(1);
    Callable<String> call = new Callable<String>() {
       public String call() throws Exception {//要限制时间的接口或方法,返回类型可以随便定义
          return ftpFile.PartsUpload(f,uploadFile.getOriginalFilename(), partsPropertyControl.getObjId());//uploadFile.getOriginalFilename(),获取上传文件名
       }
    };
    try{
       Future<String> future = exec.submit(call);
       // picture为call方法里的返回值,也就是我们方法的返回值
       picture = future.get(1000 * 3, TimeUnit.MILLISECONDS); // 任务处理超时时间设为 3 秒
       if(picture!=null && !("").equals(picture)){//FTP服务正常
          partsPropertyControl.setPicture(picture);
          partsPropertyControl.setDataState("1");
          this.partsPropertyControlService.addObject(partsPropertyControl);
          resultMap.put("msg", "添加成功");
       }else{//FTP服务异常
          resultMap.put("msg", "添加失败,请先确保正常连通FTP服务!");
       }
    }catch (Exception e){//接口或方法超过3秒后的执行
       if(picture!=null && !("").equals(picture)){//FTP服务正常
          partsPropertyControl.setPicture(picture);
          partsPropertyControl.setDataState("1");
          this.partsPropertyControlService.addObject(partsPropertyControl);
          resultMap.put("msg", "添加成功");
       }else{//FTP服务异常
          resultMap.put("msg", "添加失败,请先确保正常连通FTP服务!");
       }
    }
    exec.shutdown();//关闭线程池
    展开全文
  • spring boot 限制接口访问次数

    万次阅读 2019-06-11 16:42:27
    //接口超过请求次数 return mp; } } System.err.println("剩余次数:"+limitMap.get(sb.toString())+" 自定义key:"+sb.toString()); return joinpoint.proceed(); } } 在controller 需要 限制次数的地方...

    首先自定义一个元注解

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /** 
    * @author  作者 : 小布
    * @version 创建时间 : 2019年6月11日 下午3:54:07 
    * @explain 类说明 : 限制访问次数
    */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface LimitKey {
    	
    	//方法名称
    	String methodName() default "";
    		
    	//访问次数
    	int frequency() default 10;
    	
    	//业务KEY
    	String paramKey() default "CDPathSta";
    	
    	//请求地址
    	String url() default "";
    	
    	//过期时间
    	long timeout() default 1000;
    		
    }
    

    然后对元注解 进行 操作

    import java.util.HashMap;
    import java.util.Map;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    /** 
    * @author  作者 : 小布
    * @version 创建时间 : 2019年6月11日 下午3:57:27 
    * @explain 类说明 : 限制访问次数
    */
    @Component
    @Order
    @Aspect
    public class LimitAspect {
    
        private Map limitMap = new HashMap();
        
        
        private static final Logger log = LoggerFactory.getLogger(LimitAspect.class);
    
        @Pointcut("@annotation(limitKey)")
        public void limit(LimitKey limitKey) {
        }
    
        @Around("limit(limitKey)")
        public Object aroundLog(ProceedingJoinPoint joinpoint,LimitKey limitKey) throws Throwable {
            MethodSignature methodSignature = (MethodSignature) joinpoint.getSignature();
            int frequency = limitKey.frequency();
            String methodName = limitKey.methodName();
            String paramKey = limitKey.paramKey();
            String url = limitKey.url();
            //入参
            String[] parameterNames = methodSignature.getParameterNames();
            Object[] args = joinpoint.getArgs();
            Object obj = null ;
            
            for(int i = 0 ; i < parameterNames.length;i++) {
                if(parameterNames[i].equals(paramKey)) {
                    obj = args[i];
                    break;
                }
            }
            
            StringBuffer sb = new StringBuffer();
            sb.append(url).append("/_").append(methodName).append("_").append(paramKey).append("_").append(obj).append("_key");
            if(limitMap.get(sb.toString()) == null ) {
                 limitMap.put(sb.toString(),frequency-1);
            } else {
                 int l = (int) limitMap.get(sb.toString());
                 if(l > 0){
                     limitMap.put(sb.toString(), --l);
                 } else {
                	 Map<String, Object> mp = new HashMap<String, Object>();
                 	 mp.put("msg", 50003);//接口超过请求次数
                     return mp;
                 }
            }
            System.err.println("剩余次数:"+limitMap.get(sb.toString())+" 自定义key:"+sb.toString());
            return joinpoint.proceed();
        }
    
    }
    

    在controller 需要 限制次数的地方加上 刚刚自定义的元注解
    @LimitKey(methodName=“名称”, url=“你的地址”) 这里的参数跟刚刚定义有关

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 应用场景:应项目需求,前后台分离,增强接口安全,限制相同IP访问接口的次数有限 解决:在项目中增加事物,在进接口方法钱处理 思路: 1)@Before 在进入接口方法之前进入处理,within里面的书写表示写在控制器...

    应用场景:应项目需求,前后台分离,增强接口安全,限制相同IP访问接口的次数有限

    解决:在项目中增加事物,在进接口方法钱处理

    思路:

    1)@Before 在进入接口方法之前进入处理,within里面的书写表示写在控制器上方并且有对应注解的控制器会来到这里。

    2)用获取的IP+对应url作为key,存到redis中,如果Redis存在这个key,然后时间处理器在超过设置时间时,会将相应的key移除。

    3)如果访问超出设置限定的次数,就会重定向到返回数据接口。返回信息为请求次数过多。

    1、增加Aspects的依赖

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aspects</artifactId>

        </dependency>

    2.定义自己的注解

    package com.haidaipuhui.safeLimit;
    
    import java.lang.annotation.*;
    
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    
    /**
     * @author wangdeqiu
     * @date 2018年11月2日 下午2:19:05
     * 类说明:自定义注解限制访问时间长度最多访问次数
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Documented
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public @interface RequestLimit {
    
    	/**
         * 允许访问的最大次数
         */
        int count() default Integer.MAX_VALUE;
    
        /**
         * 时间段,单位为毫秒,默认值一分钟
         */
        long time() default 60000;
    }
    

    3.定义自己的异常类

    package com.haidaipuhui.safeLimit;
    /**
     * @author wangdeqiu
     * @date 2018年11月2日 下午2:22:28
     * 类说明:
     */
    public class RequestLimitException extends Exception{
    
    	private static final long serialVersionUID = 1555967171104727461L;
    	
    	public RequestLimitException(){
            super("HTTP请求超出设定的限制");
        }
    
        public RequestLimitException(String message){
            super(message);
        }
    
    }
    

    4.定义切点,处理逻辑

    package com.haidaipuhui.safeLimit;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import com.github.pagehelper.util.StringUtil;
    import com.haidaipuhui.service.redis.IRedisService;
    
    /**
     * @author wangdeqiu
     * @date 2018年11月2日 下午2:22:43
     * 类说明:
     */
    @Aspect
    @Component
    public class RequestLimitContract {
    
    	private static final Logger logger = LoggerFactory.getLogger(RequestLimitContract.class);
        @Autowired 
        private IRedisService redisTemplate;
        private static String limitPath="/safeLimit/limit";
    	
        @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)")
        public void requestLimit(final JoinPoint joinPoint , RequestLimit limit) throws RequestLimitException {
            try {
                Object[] args = joinPoint.getArgs();
                HttpServletRequest request = null;
                ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
                HttpServletResponse response = servletRequestAttributes.getResponse();
                for (int i = 0; i < args.length; i++) {
                    if (args[i] instanceof HttpServletRequest) {
                        request = (HttpServletRequest) args[i];
                        break;
                    }
                }
                if (request == null) {
                    throw new RequestLimitException("方法中缺失HttpServletRequest参数");
                }
                String ip = request.getLocalAddr();
                String url = request.getRequestURL().toString();
                String key = "req_limit_".concat(url).concat(ip);
                if (!redisTemplate.hasKey(key) || StringUtil.isEmpty(redisTemplate.get(key))) {
                    redisTemplate.set(key,String.valueOf(1));
                } else {
                		Integer getValue = Integer.parseInt(redisTemplate.get(key))+1;
                    redisTemplate.set(key, String.valueOf(getValue));
                }
                int count =Integer.parseInt(redisTemplate.get(key));
                if (count > 0) {
                    //创建一个定时器
                    Timer timer = new Timer();
                    TimerTask timerTask = new TimerTask() {
                        @Override
                        public void run() {
                            redisTemplate.del(key);
                        }
                    };
                    //这个定时器设定在time规定的时间之后会执行上面的remove方法,也就是说在这个时间后它可以重新访问
                    timer.schedule(timerTask, limit.time());
                }
                if (count > limit.count()) {
                    logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]");
    //                throw new RequestLimitException();
                    String toLomitPath ="http://" + request.getServerName()+ ":" + request.getServerPort()+limitPath;   //端口号
                    response.sendRedirect(toLomitPath);
                }
            }catch (RequestLimitException e){
                throw e;
            }catch (Exception e){
                logger.error("发生异常",e);
            }
        }
    
        
    }
    

    5。返回给前端信息

    package com.haidaipuhui.safeLimit;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * @author wangdeqiu
     * @date 2018年11月5日 上午11:37:45
     * 类说明:
     */
    @Controller
    @RequestMapping("safeLimit")
    public class RequestLimitExpController {
    	
    	
    	@RequestMapping(value = "/limit")
        @ResponseBody
        public Map<String, Object> safeLimitRes(HttpServletRequest request,Integer pagenum, Integer pagesize){
        		Map<String, Object> outputMap =new HashMap<String,Object>();  
        		outputMap.put("success", false);
        		outputMap.put("msg", "HTTP请求超出设定的限制");
            	return outputMap;
        }  
    
    }
    

     

    展开全文
  • 我们可以自定义注解,把注解添加到我们的接口上。定义一个切面,执行方法前去ExpiringMap查询该IP在规定时间内请求了多少次,如超过次数则直接返回请求失败。 需要用到的依赖 <!-- AOP依赖 --> <...

    需要用到的知识:注解、AOP、ExpiringMap(带有有效期的映射)

     

    我们可以自定义注解,把注解添加到我们的接口上。定义一个切面,执行方法前去ExpiringMap查询该IP在规定时间内请求了多少次,如超过次数则直接返回请求失败。

     

    需要用到的依赖

    <!-- AOP依赖 -->
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
                <version>2.1.5.RELEASE</version>
    </dependency>
    <!-- Map依赖 -->
    <dependency>
                <groupId>net.jodah</groupId>
                <artifactId>expiringmap</artifactId>
                <version>0.5.8</version>
    </dependency>

     

    自定义注解@LimitRequest

    @Documented
    @Target(ElementType.METHOD) // 说明该注解只能放在方法上面
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LimitRequest {
        long time() default 6000; // 限制时间 单位:毫秒
        int count() default 1; // 允许请求的次数
    }

     

    自定义AOP

    @Aspect
    @Component
    public class LimitRequestAspect {
    
        private static ConcurrentHashMap<String, ExpiringMap<String, Integer>> book = new ConcurrentHashMap<>();
    
        // 定义切点
        // 让所有有@LimitRequest注解的方法都执行切面方法
        @Pointcut("@annotation(limitRequest)")
        public void excudeService(LimitRequest limitRequest) {
        }
    
        @Around("excudeService(limitRequest)")
        public Object doAround(ProceedingJoinPoint pjp, LimitRequest limitRequest) throws Throwable {
    
            // 获得request对象
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            
            // 获取Map对象, 如果没有则返回默认值
            // 第一个参数是key, 第二个参数是默认值
            ExpiringMap<String, Integer> uc = book.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build());
            Integer uCount = uc.getOrDefault(request.getRemoteAddr(), 0);
    
    
    
            if (uCount >= limitRequest.count()) { // 超过次数,不执行目标方法
                return "接口请求超过次数";
            } else if (uCount == 0){ // 第一次请求时,设置有效时间
    //            /** Expires entries based on when they were last accessed */
    //            ACCESSED,
    //            /** Expires entries based on when they were created */
    //            CREATED;
                uc.put(request.getRemoteAddr(), uCount + 1, ExpirationPolicy.CREATED, limitRequest.time(), TimeUnit.MILLISECONDS);
            } else { // 未超过次数, 记录加一
                uc.put(request.getRemoteAddr(), uCount + 1);
            }
            book.put(request.getRequestURI(), uc);
    
            // result的值就是被拦截方法的返回值
            Object result = pjp.proceed();
    
            return result;
        }
    
    
    }
    

    第一个静态Map是多线程安全的Map(ConcurrentHashMap),它的key是接口对于的url,它的value是一个多线程安全且键值对是有有效期的Map(ExpiringMap)。

    ExpiringMap的key是请求的ip地址,value是已经请求的次数。

    ExpiringMap更多的使用方法可以参考:https://github.com/jhalterman/expiringmap

     

    最后在方法上面加上@LimitRequest就行了

     

    展开全文
  • nginx+lua 限制接口访问次数

    千次阅读 2017-10-24 19:54:32
    最近看了一些nginx+lua 的东西,尝试实现了一下限流脚本,只包含最...-- 此处仅仅实现 按照url 10s 内限制 2次访问,记录每次访问次数(无用仅仅用于核对代码逻辑可去除),获取参数函数已有,后续需要完善 --packag
  • 我们有的时候系统里面有的用户接口为了控制访问频率,需要使用到,笔记走一波 环境: spring spring mvc Guava:谷歌高并发工具,下面是maven <!--谷歌guava高并发处理工具--> <dependency> <...
  • 在做java web项目的时候,为了防止其他人调用接口获取数据,可以通过过滤器对调用者ip进行限制 首先写一个java类实现filter接口,会自动重写三个方法,init(),doFilter()和destory(). init()主要可以用来获取filter...
  • 很多情况下,我们需要对一些接口限制访问次数,用于防止恶意请求。 这时候,我们可以写一个工具类的方法,用于限制请求次数。 /** 尝试次数限制 * @param $key * @param $prefix //前缀,用于跟key组合存redis *...
  • Route::any(‘store’,’ApiController@store’)-&gt;middleware(‘throttle:5’); 需要注意这是对每分钟的限制
  • 接口调用频繁限制接口限制流量

    千次阅读 2018-09-27 22:04:30
    这是第一种接口的方式,可能对性能有些影响,但是同一数据只能保存一次,感觉有点麻烦,过期数据无法清理,缓存会越变越大,要考虑数据如何重复和数据清除问题,没有redis方便 并发安全的KEY static ...
  • 接口访问次数限制

    万次阅读 2016-04-05 11:34:27
    接口访问次数限制(request_limit) ================================================================================ 利用spring切面或拦截器实现; 可以对所有接口或添加注解的接口实现请求次数限制; 利用缓存的...
  • 限制后端接口的访问次数

    千次阅读 2020-06-23 09:46:25
    限制后端接口的访问次数
  • Promise实现接口超时限制

    千次阅读 2018-12-27 23:22:17
    主要思想:通过Promise.race()实现接口超时限制    // 定义上传文件接口函数 export const uploadFile= (params) =&gt; { let uri = serverSrc + '/api/xxx/xxx' // 设置请求地址 return Promise.race([ ...
  • ThinkPHP 接口请求限制

    千次阅读 2020-03-25 17:29:25
    用途:为了在程序上对某些验证接口上防止暴力破解,或者降低数据的压力可以使用这个简单的请求访问限制。 注意事项:首先要TP5开启缓存,服务器要有Redis,或者用tp5默认的文件缓存也可以。 /** * 接口请求限制 ...
  • 接口调用频次限制说明

    千次阅读 2019-03-28 00:10:00
    接口调用频次限制说明公众号调用接口并不是无限制的。为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,每个公众号调用接口都不能超过一定限制,当超过一定限制时,调用对应接口会收到如下错误返回码...
  • Android P非SDK接口限制

    千次阅读 2019-05-26 20:05:57
    Android Pie(API 28)开始对非SDK接口的使用开始做了限制.只要应用引用非 SDK 接口或尝试使用反射或 JNI 来获取其句柄,就会被限制。这些限制旨在帮助提升用户体验和开发者体验,为用户降低应用发生崩溃的风险,同时...
  • api接口访问限制

    千次阅读 2018-12-03 22:01:00
    在日常开发接口的时候,尤其是restfull接口,肯定会考虑安全或者是做一些自定义的限制,用来界定并维护代码。那么,我们都会采用什么方法那?通常来讲,我们可以通过session的形式,以访问者的ip为键来记录用户对某...
  • 限制http接口请求次数

    千次阅读 2016-12-30 10:34:59
    利用aop实现根据ip限制一个接口在一段时间内的请求次数
  • 主要介绍了nginx限制IP恶意调用短信接口处理方法,一种是nginx黑名单方式,另一种是限制IP请求数。需要的朋友可以参考下
  • 1,先看下一我的代码里边什么也没有,但是调用的话里边功能绝对不会少,并且还能规定调用次数和时间限制,例如5分钟之内只能调用几次等等. @RestController @RequestMapping("/photo") public class GoogleController { ...
  • springboot 接口频率限制

    千次阅读 热门讨论 2020-05-15 14:59:58
    针对耗时操作的接口,避免在短时间内重复请求,在后端用拦截器对请求进行拦截过滤,判断请求频率是否在合理时间范围内。 2.实现方式 @Component public class RequestFrequenceInterceptor implements ...
  • Android9.0对非 SDK 接口限制

    千次阅读 2018-10-19 12:00:59
    在 Android 9.0 版本中,谷歌加入了非 SDK 接口使用限制,无论是通过调用、反射还是JNI等方式,开发者都无法对非 SDK 接口进行访问,此接口的滥用将会带来严重的系统兼容性问题。 在开发过程中,开发者如果...
  • 微信接口调用频次限制说明

    万次阅读 2018-03-27 14:10:25
    接口调用频次限制说明公众号调用接口并不是无限制的。为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,每个公众号调用接口都不能超过一定限制,当超过一定限制时,调用对应接口会收到如下错误返回码...
  • 微信公众号接口调用频次限制说明

    万次阅读 2018-08-21 09:35:47
    为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,每个公众号调用接口都不能超过一定限制,当超过一定限制时,调用对应接口会收到如下错误返回码:   {"errcode":45009,"errmsg&...
  • Redis 实现接口访问频率限制

    千次阅读 2018-12-16 13:44:57
    Redis 实现接口访问频率限制 来源:SDK.cn 类型:技术文章 发布:2017-06-01 为什么限制访问频率 做服务接口时通常需要用到请求频率限制 Rate limiting,例如限制一个用户1分钟内最多可以范围100次 主要用来...
  • Postman请求具有拦截器(登录限制接口 方法一:注释掉拦截器。 方法二:使用cookie信息 1.登录登陆页获取cookie信息 2.正式调用接口
  • usb接口禁用,不限制键盘鼠标,禁用优盘、移动硬盘等存储设备

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 760,622
精华内容 304,248
关键字:

怎么限制接口