javaweb — 過(guò)濾器(附實(shí)現(xiàn)中文亂碼問(wèn)題)

1:過(guò)濾器概念

過(guò)濾器就是一種在請(qǐng)求目標(biāo)資源的中間組件,比喻把污水轉(zhuǎn)換成純凈水中間需要一個(gè)污水凈化設(shè)備,那么這個(gè)設(shè)備就好比一個(gè)過(guò)濾器。那么我用圖來(lái)表示過(guò)濾器(可以有多個(gè)過(guò)濾器)運(yùn)行的過(guò)程

在這里插入圖片描述

2:Filter(過(guò)濾器)接口

Filter接口包含三個(gè)方法分別是init、doFilter、 destroy下面先逐個(gè)介紹。

2.1:public void init(FilterConfig filterConfig)

這個(gè)方法主要來(lái)完成初始化過(guò)濾器,容器調(diào)用這個(gè)方法的時(shí)候,向過(guò)濾器傳遞FilterConfig對(duì)象,F(xiàn)ilterConfig的用法和ServletConfig相似,利用FilterConfig對(duì)象可以得到ServletContext對(duì)象,以及可以得到部署描述符中過(guò)濾器初始化的參數(shù)。

2.2:public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

該方法和Servlet中的service相似,當(dāng)客戶(hù)端請(qǐng)求目標(biāo)資源的時(shí)候,容器就會(huì)調(diào)用與這個(gè)目標(biāo)資源相關(guān)聯(lián)的過(guò)濾器的doFilter方法,在這個(gè)方法中可以對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理,實(shí)現(xiàn)過(guò)濾器的特定功能,在處理完成之后調(diào)用chain.doFilter把請(qǐng)求傳給下一個(gè)過(guò)濾器(目標(biāo)資源)

2.3:public void destroy()

當(dāng)過(guò)濾器生命結(jié)束的時(shí)候,容器就會(huì)調(diào)用該方法來(lái)釋放過(guò)濾器的資源

3:過(guò)濾器的配置

過(guò)濾器是通過(guò)<filter>和<filter-mapping>元素來(lái)完成的。

3.1:<filter>元素

<filter>元素的屬性,<filter-name>來(lái)為過(guò)濾器指定一個(gè)名字,<filter-class>元素用于指定過(guò)濾器完整的限定類(lèi)名,<init-param>用來(lái)為過(guò)濾器指定初始化參數(shù),他下面有2個(gè)屬性,一個(gè)是<param-name>參數(shù)名稱(chēng),另一個(gè)是<param-value>參數(shù)值。

3.2:<filter-mapping>元素

<filter-mapping>下面有3個(gè)主要的屬性,<filter-name>用來(lái)指定過(guò)濾已經(jīng)在容器聲明的過(guò)濾器名稱(chēng),<url-pattren><servlet-name>這兩個(gè)任選其中一個(gè),<url-pattren>表示當(dāng)請(qǐng)求這樣的url時(shí)候過(guò)濾器被調(diào)用,<servlet-name>表示當(dāng)這個(gè)Servlet被調(diào)用時(shí)候過(guò)濾器被調(diào)用(可以有多個(gè)Servlet)。

基本知識(shí)準(zhǔn)備完畢了,現(xiàn)在我們一起開(kāi)始進(jìn)行實(shí)踐。

4:過(guò)濾器時(shí)間應(yīng)用

4.1:過(guò)濾器解決中文亂碼問(wèn)題

由于Web容器默認(rèn)的編碼方式是ISO-8859-1,在Servlet/Jsp程序中,通過(guò)請(qǐng)求的對(duì)象的getParameter()方法得到的字符串是以ISO-8859-1轉(zhuǎn)換而來(lái)(有人說(shuō)我在jsp程序已經(jīng)設(shè)置了UTF-8為什么還出現(xiàn)這種情況呢,那是由于web容器再次對(duì)請(qǐng)求的數(shù)據(jù)進(jìn)行一次轉(zhuǎn)換,所以后來(lái)得到字符串就是ISO-8859-1編碼的),這就是導(dǎo)致亂碼的原因。如下圖


在這里插入圖片描述

那么找到根源以后問(wèn)題就比較好解決了,核心代碼如下

public class EncodingFilter implements Filter {

    protected String encoding=null; 
    class myRequestWrapper extends HttpServletRequestWrapper{

        public myRequestWrapper(HttpServletRequest request) {
            super(request);
        }
        public String getParameter(String param)
        {
            String value=null;
            try{
                //post提交
                super.setCharacterEncoding(encoding);
                value=super.getParameter(param);
                if(super.getMethod().equalsIgnoreCase("GET"))//get提交
                {
                    if(value!=null)
                    {
                        value=new String(value.getBytes("iso8859-1"), encoding);
                    }
                }        
            }
            catch(UnsupportedEncodingException e){
                e.printStackTrace();
            }        
            return value;
        }
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        this.encoding=filterConfig.getInitParameter("encoding");//從web容器來(lái)獲取過(guò)濾器初始化參數(shù)
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        //避免響應(yīng)出現(xiàn)亂碼情況
        response.setCharacterEncoding("text/html;charset="+this.encoding);
        //把過(guò)濾器給下一個(gè)過(guò)濾器或者資源處理器
        chain.doFilter(new myRequestWrapper((HttpServletRequest)request), response);
    }

    public void destroy() {
        this.encoding=null;
    }
}

對(duì)過(guò)濾器進(jìn)行配置

<filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.lp.filters.EncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <servlet-name>LoginServlet</servlet-name>
        <!-- <url-pattern>/LoginServlet</url-pattern> -->
    </filter-mapping>

5:過(guò)濾器使用場(chǎng)景

5.1:對(duì)用戶(hù)進(jìn)行統(tǒng)一驗(yàn)證
5.2:對(duì)用戶(hù)的訪(fǎng)問(wèn)要求進(jìn)行記錄或者審核
5.3:對(duì)用戶(hù)請(qǐng)求發(fā)送的數(shù)據(jù)進(jìn)行過(guò)濾或替換
5.4:轉(zhuǎn)換圖像格式
5.5:對(duì)響應(yīng)的內(nèi)容進(jìn)行壓縮,減少傳輸量
5.6:對(duì)請(qǐng)求和響應(yīng)進(jìn)行加解密處理
5.7:觸發(fā)資源訪(fǎng)問(wèn)事件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容