最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java利用redis限制用戶(hù)頻繁點(diǎn)擊操作

 更新時(shí)間:2026年04月27日 10:10:49   作者:考拉在編程  
文章討論了如何使用Redis和攔截器來(lái)限制用戶(hù)行為,以保障系統(tǒng)安全,具體來(lái)說(shuō),作者提出了一種解決方案,包括使用注解來(lái)精確限制用戶(hù)行為,并 使用攔截器記錄并處理用戶(hù)行為,文章還指出,需要添加crosFilter方法來(lái)解決攔截器的跨域問(wèn)題

一、場(chǎng)景

為了系統(tǒng)安全,有時(shí)候需要做一些限制用戶(hù)的操作。比如用戶(hù)惡意刷接口,或者系統(tǒng)卡頓時(shí)候頻繁點(diǎn)擊,輕則造成系統(tǒng)崩潰,重則可能造成數(shù)據(jù)丟失。不得不引起重視。

解決方案:使用redis和攔截器來(lái)記錄并控制用戶(hù)行為

二、攔截器

 ResponseParams為本地的一個(gè)異常處理對(duì)象,自己可以使用自己的對(duì)象

package simple.cloud.config.myInterceptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import net.sf.json.JSONArray;
import simple.cloud.components.common.params.ResponseParams;
import simple.cloud.components.common.utils.MyUtils;
@Component
@CrossOrigin("*")
public class MyInterceptor implements HandlerInterceptor {
	@Resource 
	private RedisTemplate<String, Object> redisTemplate;
	/**
	 * 1、過(guò)濾封禁IP 
     * 2、過(guò)濾惡意IP
	 */
	@Override
	@CrossOrigin("*")
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (handler.getClass().isAssignableFrom(HandlerMethod.class)) { // 判斷此class對(duì)象所表示的類(lèi)或接口與指定的class參數(shù)所表示的類(lèi)或接口是否相同
			//1、校驗(yàn)IP合法
			String ip = MyUtils.getIpAddress(request);
			String limitKey = request.getServletPath() + MyUtils.getIpAddress(request);
			Object blackIp = redisTemplate.opsForValue().get(ip);
			if (MyUtils.isNotNull(blackIp)) {
				respouseOut(response, ResponseParams.error("禁止使用!"));
				return false;
			}
			//2、校驗(yàn)重復(fù)點(diǎn)擊
//          HandlerMethod封裝方法定義相關(guān)的信息,如類(lèi)、方法、參數(shù)等
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();
//           獲取方法中是否包含注解
			MyLimit methodAnnotation = method.getAnnotation(MyLimit .class);
//           獲取類(lèi)中是否包含注解
			MyLimit classAnnotation = method.getDeclaringClass().getAnnotation(MyLimit .class);
//           如果方法上有注解 就優(yōu)先選擇方法上的參數(shù)
			MyLimit myLimit = methodAnnotation != null ? methodAnnotation : classAnnotation;
			if (requestLimit != null) {
				if (checkLimit(limitKey, myLimit )) {
					respouseOut(response, ResponseParams.error("您點(diǎn)擊的太頻繁啦!"));
                    //將被封禁的IP加入緩存,下次訪問(wèn)時(shí)不必校驗(yàn)其點(diǎn)擊情況
					redisTemplate.opsForValue().set(ip  , 1, 30, TimeUnit.SECONDS);
					return false;
				}
			}
		}
		return true;
	}
	/**
	 * 回寫(xiě)給客戶(hù)端
	 */
	private void respouseOut(HttpServletResponse response, ResponseParams resp) throws IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json;charaset=utf-8");
		PrintWriter out = null;
		String json = com.alibaba.fastjson.JSONObject.toJSON(resp).toString();
		out = response.getWriter();
		out.append(json);
	}
	/**
	 * 判斷請(qǐng)求是否受限
	 */
	private boolean checkLimit(String limitKey, RequestLimit requestLimit) {
        //使用IP+請(qǐng)求地址作為key
        //從緩存中獲取,當(dāng)前這個(gè)請(qǐng)求訪問(wèn)了幾次
		Integer redisCount = (Integer) redisTemplate.opsForValue().get(limitKey);
		if (redisCount == null) {
            //初始次數(shù)
			redisTemplate.opsForValue().set(limitKey, 1, requestLimit.second(), TimeUnit.SECONDS);
		} else {
            //若在指定時(shí)間內(nèi)超過(guò)了訪問(wèn)次數(shù)限制,則返回true
			if (redisCount.intValue() >= requestLimit.maxCount()) {
			   //將其設(shè)置超過(guò)限制次數(shù),并延遲30秒,30秒之后可以重新訪問(wèn)
			   redisTemplate.opsForValue().set(limitKey, requestLimit.maxCount()+1, 30, TimeUnit.SECONDS);
				return true;
			}
            //次數(shù)自增
			redisTemplate.opsForValue().increment(limitKey, 1);
		}
		return false;
	}
}

 MyLimit為一個(gè)注解,可以添加在指定controller上,來(lái)精確限制用戶(hù)行為

@Documented
@Inherited
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLimit {
    int second() default 1;
    int maxCount() default 15;
}

三、添加攔截器

 值得注意的是需要添加crosFiter方法,來(lái)解決攔截器跨越問(wèn)題

@Resource
    private MyInterceptor myInterceptor;
	/**
	 * 讓cors高于攔截器的權(quán)限
	 * 解決攔截器CROS問(wèn)題
	 * @return
	 */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.setAllowCredentials(true);
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }
    /**
     * 添加我的默認(rèn)的攔截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }

到此這篇關(guān)于Java利用redis限制用戶(hù)頻繁點(diǎn)擊操作的文章就介紹到這了,更多相關(guān)java redis限制頻繁點(diǎn)擊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java獲取日期的方法

    java獲取日期的方法

    這篇文章介紹了java獲取日期的方法,有需要的朋友可以參考一下
    2013-10-10
  • Java中BigDecimal精度和相等比較的坑

    Java中BigDecimal精度和相等比較的坑

    BigDecimal是一種精確的數(shù)字類(lèi),一般用于高精度的開(kāi)發(fā)領(lǐng)域中,例如銀行。下面這篇文章主要給大家介紹了關(guān)于Java中BigDecimal精度和相等比較的坑的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-09-09
  • 基于java使用JavaMail發(fā)送郵件

    基于java使用JavaMail發(fā)送郵件

    這篇文章主要介紹了基于java使用JavaMail發(fā)送郵件 ,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。
    2016-12-12
  • SpringMVC DispatcherServlet組件實(shí)現(xiàn)解析

    SpringMVC DispatcherServlet組件實(shí)現(xiàn)解析

    這篇文章主要介紹了SpringMVC DispatcherServlet組件實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java?MethodHandles介紹與反射對(duì)比區(qū)別詳解

    Java?MethodHandles介紹與反射對(duì)比區(qū)別詳解

    這篇文章主要為大家介紹了Java?MethodHandles介紹與反射對(duì)比區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Spring如何基于aop實(shí)現(xiàn)操作日志功能

    Spring如何基于aop實(shí)現(xiàn)操作日志功能

    這篇文章主要介紹了Spring如何基于aop實(shí)現(xiàn)操作日志功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • MyBatisPlus 自定義sql語(yǔ)句的實(shí)現(xiàn)

    MyBatisPlus 自定義sql語(yǔ)句的實(shí)現(xiàn)

    這篇文章主要介紹了MyBatisPlus 自定義sql語(yǔ)句的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決

    Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決

    這篇文章主要介紹了Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • IDEA如何設(shè)置忽略git提交的文件

    IDEA如何設(shè)置忽略git提交的文件

    這篇文章主要介紹了IDEA如何設(shè)置忽略git提交的文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • springboot中websocket簡(jiǎn)單實(shí)現(xiàn)

    springboot中websocket簡(jiǎn)單實(shí)現(xiàn)

    本文主要介紹了springboot中websocket簡(jiǎn)單實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01

最新評(píng)論

汾西县| 南城县| 乌鲁木齐县| 文成县| 新巴尔虎右旗| 赫章县| 肥西县| 文昌市| 亚东县| 景谷| 苏州市| 胶南市| 长葛市| 广宁县| 西林县| 吉安县| 会昌县| 泗洪县| 平乡县| 西青区| 五寨县| 砚山县| 炎陵县| 洛阳市| 朝阳县| 西吉县| 沐川县| 桑植县| 瑞安市| 西充县| 富裕县| 双桥区| 浮梁县| 微博| 米易县| 当涂县| 云林县| 文登市| 高台县| 宁化县| 酒泉市|