過濾器

過濾器

概述
    在請求與響應(yīng)數(shù)據(jù)之間,添加過濾
    過濾器就是一個(gè)接口
    javax.servlet.Filter
作用
    過濾器是一個(gè)對象结缚,可以在請求資源時(shí),或者在響應(yīng)資源時(shí),或者在請求和響應(yīng)資源時(shí)秸架,執(zhí)行過濾任務(wù)础爬。
工作原理
    瀏覽器發(fā)起的所有請求被過濾器攔截
    過濾有效的請求給控制器
    控制器響應(yīng)數(shù)據(jù)被過濾器攔截
    返回瀏覽器
生命周期
    實(shí)例化
    初始化
    執(zhí)行過濾
    銷毀
    init(FilterConfig)
        初始化方法叠赦,在創(chuàng)建過濾器對象后調(diào)用
    doFilter(request,response,FilterChain) 
        每次訪問目標(biāo)資源時(shí)都被調(diào)用
    destory()  
        過濾器對象銷毀時(shí)調(diào)用
        web應(yīng)用重新加載或web服務(wù)器停止了
應(yīng)用場合
    對請求和響應(yīng)進(jìn)行統(tǒng)一處理
    對請求進(jìn)行日志記錄和審核
    對數(shù)據(jù)進(jìn)行屏蔽和替換
    對數(shù)據(jù)進(jìn)行加密和解密
    參數(shù)進(jìn)行中文編碼處理
    登錄權(quán)限問題
API
    Filter接口
        Filter接口沒有實(shí)現(xiàn)類,編寫過濾器必須要實(shí)現(xiàn)該接口
        常用方法
            void init(FilterConfig filterConfig)    
                Web容器調(diào)用該方法實(shí)現(xiàn)過濾器的初始化
            void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)   
                客戶端請求資源時(shí)卷拘,Web容器會調(diào)用與資源對應(yīng)的過濾器的doFilter()方法。在該方法中祝高,可以對請求和響應(yīng)進(jìn)行處理栗弟,實(shí)現(xiàn)過濾器的功能
            void destory()  
                Web容器調(diào)用該方法,造成過濾器失效
開發(fā)步驟
    1.定義一個(gè)類OneFilter實(shí)現(xiàn)javax.servlet.Filter
    2.實(shí)現(xiàn)doFilter方法
        chain.doFilter(request,response);//是放行
    3.web.xml配置
        <filter>
            <filter-name></filter-name>
            <filter-class></filter-class>
        </filter>
        <filter-mapping>
            <filter-name></filter-name>
            <url-pattern></url-pattern>
        </filter-mapping>
過濾器鏈
    多個(gè)過濾器組成過濾器鏈
    根據(jù)過濾器的配置工闺,按照先后順序執(zhí)行
    按照filter-mapping配置的順序來執(zhí)行
初始化參數(shù)設(shè)置
    <filter>
        <filter-name>onefilter</filter-name>
        <filter-class>com.shuai.filters.OneFilter</filter-class>
        <init-param>
            <param-name>user</param-name>
            <param-value>shuaige</param-value>
        </init-param>
    </filter>
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        String user = arg0.getInitParameter("user");
    }
過濾器映射配置
                url-pattern     目標(biāo)資源訪問      
    精確過濾      /hello            /hello
                /itcast/hello    /itcast/hello

    模糊過濾      /*                /任意路徑 
                /itcast/         /itcast/任意路徑 
                *.后綴             任意路徑.后綴
過濾內(nèi)容
    一個(gè)過濾器可以同時(shí)過濾多個(gè)資源(靜態(tài)或者動態(tài)的)
    如果資源是動態(tài)的servlet乍赫,可以使用名稱進(jìn)行過濾
過濾類型
    <dispatcher>類型值</dispatcher>
    過濾類型:在什么樣的請求下,過濾器才會生效陆蟆!
        REQUEST:直接通過發(fā)出的請求   (默認(rèn))
        FORWARD:通過轉(zhuǎn)發(fā)過來的請求
        INCLUDE:通過包含方式過來的請求
        ERROR:通過錯(cuò)誤頁面的方法過來的請求
什么是過濾器鏈
    當(dāng)一個(gè)資源同時(shí)被多個(gè)過濾器所過濾雷厂,則形成一個(gè)過濾器鏈
    注意:filter-mapping配置的順序決定了過濾器鏈中過濾調(diào)用的順序:先配置先被調(diào)用
案例
    編碼過濾器
        public class MyRequest extends HttpServletRequestWrapper {
            private HttpServletRequest request;
            public MyRequest(HttpServletRequest request) {
                super(request);
                this.request = request;
            }
            @Override
            public String getParameter(String name) {
                try {
                    String value = request.getParameter(name);
                    if("get".equalsIgnoreCase(request.getMethod())){
                        value = new String(value.getBytes("iso-8859-1"),"utf-8");
                    }
                    return value;
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
            @Override
            public String[] getParameterValues(String name) {
                try {
                    String[] values = request.getParameterValues(name);
                    if("get".equalsIgnoreCase(request.getMethod())){
                        for(int i = 0;i<values.length;i++){
                            values[i] = new String(values[i].getBytes("iso-8859-1"),"utf-8");
                        }
                    }
                    return values;
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
            @Override
            public Map getParameterMap() {
                try {
                    Map<String,String[]> map = request.getParameterMap();
                    if("get".equalsIgnoreCase(request.getMethod())){
                        for(Entry<String,String[]> entry:map.entrySet()){
                            String[] values = entry.getValue();
                            for(int i=0;i<values.length;i++){
                                values[i] = new String(values[i].getBytes("iso-8859-1"),"utf-8");
                            }
                        }
                    }
                    return map;
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }
        public class EncodeFilter implements Filter {
            @Override
            public void destroy() {
            }
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException {
                request.setCharacterEncoding("utf-8");
                MyRequest myRequest = new MyRequest((HttpServletRequest)request);
                chain.doFilter(myRequest, response);
            }
            @Override
            public void init(FilterConfig arg0) throws ServletException {
            }
        }
    頁面壓縮過濾器
        public class MyResponse extends HttpServletResponseWrapper {
            private HttpServletResponse response;
            private CharArrayWriter buffer = new CharArrayWriter();
            public MyResponse(HttpServletResponse response) {
                super(response);
                this.response = response;
            }
            public char[] getBuffer(){
                return buffer.toCharArray();
            }
            @Override
            public PrintWriter getWriter() throws IOException {
                //返回一個(gè)帶CharArrayWriter緩存的PrintWriter對象
                return new PrintWriter(buffer);
            }
        }
        public class ContentGZIPFilter implements Filter {
            public void doFilter(ServletRequest request, ServletResponse response,
                    FilterChain chain) throws IOException, ServletException {
                MyResponse myResponse = new MyResponse((HttpServletResponse)response);
                //放行
                chain.doFilter(request, myResponse);
                //得到壓縮前的內(nèi)容
                char[] content = myResponse.getBuffer();
                System.out.println(new String(content).getBytes().length);
                // 對網(wǎng)頁內(nèi)容進(jìn)行壓縮
                // 1)創(chuàng)建臨時(shí)緩存區(qū)用于存放壓縮后的內(nèi)容
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                // 2)創(chuàng)建GZIPOutputStream對象
                GZIPOutputStream gzip = new GZIPOutputStream(bos);
                // 3)開始壓縮(內(nèi)容壓縮到緩存區(qū)中)
                gzip.write(new String(content).getBytes("UTF-8"));
                // 壓縮結(jié)束
                gzip.finish();
                // 4)從緩存區(qū)取出壓縮后的內(nèi)容
                byte[] result = bos.toByteArray();
                System.out.println("壓縮后:" + result.length);
                // 通知瀏覽器數(shù)據(jù)壓縮格式
                myResponse.setHeader("content-encoding", "gzip");
                // 把壓縮后的內(nèi)容寫出到瀏覽器
                response.getOutputStream().write(result);
            }
            public void init(FilterConfig filterConfig) throws ServletException {}
            public void destroy() {}
        }
    登錄過濾器

裝飾者模式

裝飾者使用場景
    一個(gè)類的方法不能滿足開發(fā)者的需求,這時(shí)就可以使用裝飾者模式叠殷,對該類進(jìn)行裝飾改鲫,對其方法進(jìn)行(增強(qiáng))。
    讓BufferedReader的readLine方法自動帶上一個(gè)編號(增強(qiáng)方法)林束,這時(shí)可以裝飾BufferedReader
裝飾步驟:
    編寫一個(gè)裝飾類像棘,繼承被裝飾類(BufferedReader)(非final的)
    聲明一個(gè)被裝飾類的成員變量
    在裝飾類的構(gòu)造方法中,接收被裝飾類的實(shí)例
    增強(qiáng)被裝飾類的方法
代理模式 vs 裝飾者模式
    代理模式:著重于得到被代理類的方法的控制權(quán)
    裝飾者模式:著重于增強(qiáng)被裝飾類的方法內(nèi)容    
案例
    服務(wù)器編碼過濾器
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壶冒,一起剝皮案震驚了整個(gè)濱河市缕题,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌依痊,老刑警劉巖避除,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怎披,死亡現(xiàn)場離奇詭異,居然都是意外死亡瓶摆,警方通過查閱死者的電腦和手機(jī)凉逛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來群井,“玉大人状飞,你說我怎么就攤上這事∈樾保” “怎么了诬辈?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荐吉。 經(jīng)常有香客問我焙糟,道長,這世上最難降的妖魔是什么样屠? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任穿撮,我火速辦了婚禮,結(jié)果婚禮上痪欲,老公的妹妹穿的比我還像新娘悦穿。我一直安慰自己,他們只是感情好业踢,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布栗柒。 她就那樣靜靜地躺著,像睡著了一般知举。 火紅的嫁衣襯著肌膚如雪瞬沦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天负蠕,我揣著相機(jī)與錄音蛙埂,去河邊找鬼。 笑死遮糖,一個(gè)胖子當(dāng)著我的面吹牛绣的,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播欲账,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼屡江,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赛不?” 一聲冷哼從身側(cè)響起惩嘉,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎踢故,沒想到半個(gè)月后文黎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惹苗,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年耸峭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了桩蓉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劳闹,死狀恐怖院究,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情本涕,我是刑警寧澤业汰,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站菩颖,受9級特大地震影響样漆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晦闰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一氛濒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鹅髓,春花似錦、人聲如沸京景。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽确徙。三九已至醒串,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鄙皇,已是汗流浹背芜赌。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伴逸,地道東北人缠沈。 一個(gè)月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像错蝴,于是被迫代替她去往敵國和親洲愤。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Servlet過濾器是 Servlet 程序的一種特殊用法顷锰,主要用來完成一些通用的操作柬赐,如編碼的過濾、判斷用戶的登...
    重山楊閱讀 1,213評論 0 12
  • 僅作為自己學(xué)習(xí)記錄使用官紫,文章來自: 1肛宋、http://blog.csdn.net/csh624366188/art...
    BakerZhang閱讀 1,009評論 1 5
  • 創(chuàng)建 編寫一個(gè)過濾器的類州藕,實(shí)現(xiàn)Filter接口 實(shí)現(xiàn)接口尚未實(shí)現(xiàn)的方法,著重實(shí)現(xiàn)doFilter方法 在web.x...
    蕊er閱讀 431評論 0 0
  • Filter的使用和經(jīng)典案例 一酝陈、什么是Filter Filter也稱之為過濾器床玻。 通過Filter可以攔截所有對...
    明天你好向前奔跑閱讀 1,154評論 0 5
  • 通過之前發(fā)布的《Spring Cloud構(gòu)建微服務(wù)架構(gòu)(五)服務(wù)網(wǎng)關(guān)》一文,相信大家對于Spring Cloud ...
    程序猿DD閱讀 1,879評論 0 10