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

SpringBoot實(shí)現(xiàn)過濾器Filter的三種方式

 更新時(shí)間:2023年08月17日 11:08:25   作者:Hi Bug  
過濾器Filter由Servlet提供,基于函數(shù)回調(diào)實(shí)現(xiàn)鏈?zhǔn)綄?duì)網(wǎng)絡(luò)請(qǐng)求與響應(yīng)的攔截與修改,本文講給大家詳細(xì)介紹SpringBoot實(shí)現(xiàn)過濾器Filter的三種方式,需要的朋友可以參考下

過濾器 Filter 由 Servlet 提供,基于函數(shù)回調(diào)實(shí)現(xiàn)鏈?zhǔn)綄?duì)網(wǎng)絡(luò)請(qǐng)求與響應(yīng)的攔截與修改。由于基于 Servlet ,其可以對(duì)web服務(wù)器管理的幾乎所有資源進(jìn)行攔截(JSP、圖片文件、HTML 文件、CSS文件等)。

Filter 的生命周期

  • init(): 初始化Filter 實(shí)例,F(xiàn)ilter 的生命周期與 Servlet 是相同的,也就是當(dāng) Web 容器(tomcat)啟動(dòng)時(shí),調(diào)用 init() 方法初始化實(shí)例,F(xiàn)ilter只會(huì)初始化一次。需要設(shè)置初始化參數(shù)的時(shí)候,可以寫到init()方法中。
  • doFilter(): 業(yè)務(wù)處理,攔截要執(zhí)行的請(qǐng)求,對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理,一般需要處理的業(yè)務(wù)操作都在這個(gè)方法中實(shí)現(xiàn)
  • destroy() : 銷毀實(shí)例,關(guān)閉容器時(shí)調(diào)用 destroy() 銷毀 Filter 的實(shí)例。

方式① 使用Filter接口

1、在啟動(dòng)類添加注解@ServletComponentScan ,讓 Spring 可以掃描到。
2、通過 @WebFilter 注解,將類聲明為 Bean 過濾器類。此時(shí)可以指定要攔截的url , 但是不能指定過濾器執(zhí)行順序。

@Slf4j
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //獲取訪問 ip 地址
        String ipAddr = getIpAddr(request);
        // 存入緩存10s不允許訪問
        String key = new StringBuilder().append("bizKey").append(ipAddr).toString();
        if (redisTemplate.hasKey(key)) {
            // 訪問次數(shù)自增1
            redisTemplate.opsForValue().increment(key, 1);
            log.warn("訪問過快,存在強(qiáng)刷行為!key={}", key);
        } else {
            // 第一次訪問
            redisTemplate.opsForValue().set(key, 1, 10,
                    TimeUnit.SECONDS);
        }
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } catch (Exception e) {
            log.warn("認(rèn)證失敗,e:{},url:{},parameters:{}", e,request.getRequestURL(),request.getParameterMap());
            servletResponse.setContentType("application/json");
            servletResponse.setCharacterEncoding("UTF-8");
            servletResponse.getWriter().write(JSONUtil.toJsonStr(Result.fail("業(yè)務(wù)執(zhí)行報(bào)錯(cuò)~")));
        }
    }
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
    public static String getIpAddr(HttpServletRequest request){
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("X-Forwarded-For");
            if (ipAddress != null && ipAddress.length() != 0 && !"unknown".equalsIgnoreCase(ipAddress)) {
                // 多次反向代理后會(huì)有多個(gè)ip值,第一個(gè)ip才是真實(shí)ip
                if (ipAddress.indexOf(",") != -1) {
                    ipAddress = ipAddress.split(",")[0];
                }
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
            }
        }catch (Exception e) {
        }
        return ipAddress;
    }
}

方式② 使用@Component注解

使用@Component注解后,可以使用@Order注解保證過濾器執(zhí)行順序,@Order 注解用于指定組件的執(zhí)行順序,其中值越小的組件優(yōu)先執(zhí)行。

@Component
@Order(1)
public class MyFilter1 implements Filter {
    // ...
}
@Component
@Order(2)
public class MyFilter2 implements Filter {
    // ...
}

注意:

1、不使用@Order注解,則按照filter類名的字母順序來執(zhí)行

2、方式②可以保證執(zhí)行順序, 但是過濾器不能指定攔截的url , 只能默認(rèn)攔截全部

方式③ Java Config 配置類

使用 @Configuration + @Bean 配置類,注解聲明Bean,交由 Spring 容器管理。此方式既能攔截Url,也能指定執(zhí)行順序

Java Config 的方式可以通過 @Bean 配置順序或 FilterRegistrationBean.setOrder() 決定 Filter 執(zhí)行順序。(在啟動(dòng)類配置攔截器,此時(shí)自定義過濾器不加注解,為普通類即可) 可以指定過濾器要攔截的url 和 過濾器執(zhí)行順序, 但需要代碼方式實(shí)現(xiàn).

public class MyFilter1 implements Filter {
    // ...
}
public class MyFilter2 implements Filter {
    // ...
}

通過在springboot的configuration中配置不同的FilterRegistrationBean實(shí)例,來注冊(cè)自定義過濾器

這里創(chuàng)建一個(gè)configuration類

@Configuration
public class DemoConfiguration {
    @Bean
    public FilterRegistrationBean RegistTest1(){
        //通過FilterRegistrationBean實(shí)例設(shè)置優(yōu)先級(jí)可以生效
        //通過@WebFilter無效
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new Test1Filter());//注冊(cè)自定義過濾器
        bean.setName("flilter1");//過濾器名稱
        bean.addUrlPatterns("/*");//過濾所有路徑
        bean.setOrder(1);//優(yōu)先級(jí),最頂級(jí)
        return bean;
    }
    @Bean
    public FilterRegistrationBean RegistTest2(){
        //通過FilterRegistrationBean實(shí)例設(shè)置優(yōu)先級(jí)可以生效
        //通過@WebFilter無效
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new Test2Filter());//注冊(cè)自定義過濾器
        bean.setName("flilter2");//過濾器名稱
        bean.addUrlPatterns("/test/*");//過濾所有路徑
        bean.setOrder(6);//優(yōu)先級(jí),越低越優(yōu)先
        return bean;
    }
}

以上就是SpringBoot實(shí)現(xiàn)過濾器Filter的三種方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot實(shí)現(xiàn)過濾器Filter的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • eclipse下整合springboot和mybatis的方法步驟

    eclipse下整合springboot和mybatis的方法步驟

    這篇文章主要介紹了eclipse下整合springboot和mybatis的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • 全面解讀Spring Boot 中的Profile配置體系

    全面解讀Spring Boot 中的Profile配置體系

    配置體系是基于 Spring Boot 框架開發(fā)應(yīng)用程序的基礎(chǔ),而自動(dòng)配置也是該框架的核心功能之一。本文梳理Spring Boot 中的Profile配置體系的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Spring-Retry的使用詳解

    Spring-Retry的使用詳解

    在日常的一些場(chǎng)景中, 很多需要進(jìn)行重試的操作.而spring-retry是spring提供的一個(gè)基于spring的重試框架,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-11-11
  • mybatis多個(gè)plugins的執(zhí)行順序解析

    mybatis多個(gè)plugins的執(zhí)行順序解析

    這篇文章主要介紹了mybatis多個(gè)plugins的執(zhí)行順序解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • MyBatisPlus數(shù)據(jù)權(quán)限控制實(shí)現(xiàn)的三種方式

    MyBatisPlus數(shù)據(jù)權(quán)限控制實(shí)現(xiàn)的三種方式

    數(shù)據(jù)權(quán)限是保障數(shù)據(jù)安全的重要手段,本文主要介紹了MyBatisPlus數(shù)據(jù)權(quán)限控制實(shí)現(xiàn)的三種方式,具有一定的參考價(jià)值,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Java中內(nèi)部類使用方法實(shí)戰(zhàn)案例分析

    Java中內(nèi)部類使用方法實(shí)戰(zhàn)案例分析

    這篇文章主要介紹了Java中內(nèi)部類使用方法,結(jié)合具體案例形式分析了Java內(nèi)部類原理、調(diào)用方法及相關(guān)使用注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Java中的異常處理用法及其架構(gòu)和使用建議

    Java中的異常處理用法及其架構(gòu)和使用建議

    Java同樣也提供了拋出異常、捕捉異常和finally語句的使用來處理程序異常,下面就來具體看一下Java中的異常處理用法及其架構(gòu)和使用建議:
    2016-06-06
  • Java中進(jìn)程、協(xié)程與線程的區(qū)別詳解

    Java中進(jìn)程、協(xié)程與線程的區(qū)別詳解

    這篇文章主要介紹了Java中進(jìn)程,線程,協(xié)程的概念、區(qū)別以及使用場(chǎng)景的選擇,早期的操作系統(tǒng)每個(gè)程序就是一個(gè)進(jìn)程,知道一個(gè)程序運(yùn)行完,才能進(jìn)行下一個(gè)進(jìn)程,就是"單進(jìn)程時(shí)代",一切的程序只能串行發(fā)生,需要的朋友可以參考下
    2023-08-08
  • 深入淺析SSH的三個(gè)組件ssh、sftp、scp

    深入淺析SSH的三個(gè)組件ssh、sftp、scp

    SSH 包含3個(gè)組件,文中給大家詳細(xì)提到。這篇文章主要介紹了SSH的三個(gè)組件ssh、sftp、scp ,需要的朋友可以參考下
    2018-10-10
  • 淺談Java中的hashcode方法(推薦)

    淺談Java中的hashcode方法(推薦)

    本篇文章主要介紹了Java中的hashcode方法,詳細(xì)的介紹了hashCode方法的作用,具有一定的參考價(jià)值,有需要的可以了解一下。
    2016-12-12

最新評(píng)論

巴彦县| 丰县| 白山市| 灵川县| 瑞丽市| 灵丘县| 平罗县| 广水市| 镇宁| 滨州市| 陇西县| 龙岩市| 楚雄市| 阜新市| 罗田县| 通海县| 鸡泽县| 连城县| 调兵山市| 栖霞市| 文登市| 卢龙县| 溧水县| 莲花县| 汕头市| 武功县| 武穴市| 波密县| 郁南县| 贞丰县| 肇庆市| 南城县| 平江县| 海口市| 临泽县| 安康市| 湘乡市| 潢川县| 栾川县| 昔阳县| 康保县|