Filter實現全站違法關鍵詞屏蔽


思路:客戶端請求服務器數據,經過Filter過濾(請求放行,響應攔截),服務器向客戶端返回數據時,在Filter中修改掉返回數據中違法的部分。

修改服務器的響應需要自定義一個HttpServletResponse的包裝類,繼承自HttpServletResponseWrapper即可實現自己的HttpServletResponse的包裝類。

大概是這樣的:

//package com.ecshop.tools;
import java.io.CharArrayWriter;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class ShieldKeywordResponseWrapper extends HttpServletResponseWrapper{
    private CharArrayWriter caw;
    private PrintWriter pw;
    public ShieldKeywordResponseWrapper(HttpServletResponse response) {
        super(response);
        // 這個是我們保存返回結果的地方
        caw = new CharArrayWriter();
        // 這個是包裝PrintWriter的,讓所有結果通過這個PrintWriter寫入到caw中
        pw = new PrintWriter(caw);
    }
    @Override
    public PrintWriter getWriter() {
        return pw;
    }
    public String getResult() {
        return caw.toString();
    }   
}

因為違法關鍵詞都包含在響應文本消息中,服務器向請求客戶端響應文本消息必須獲取HttpServletResponse對象中的PrintWriter文本輸出流對象進行輸出消息,所以我們的這個封裝類覆蓋HttpServletResponse的getWriter是很重要的一步,我這個封裝類的意思是讓服務器響應數據時使用我們修改過的PrintWriter文本輸出流,輸出的數據並不立刻響應給客戶,而是把輸出的數據都保留在了CharArrayWriter這個對象中,當控制層執行完畢我們就可以在Filter中進行獲取CharArrayWriter對象中的數據進行修改了,修改完畢我們在返回給你客戶,就是我們想要的效果了。(而默認HttpServletResponse的PrintWriter對象是由tomcat自己所擴展自PrintWriter的CoyoteWriter對象,CoyoteWriter對象所打印的數據都保留在OutputBuffer對象(也是tomcat自己所擴展自Writer的一個對象)中,我們不方便獲取它的文本數據,所以我們修改掉它,當OutputBuffer執行flush就發送消息,或者不執行讓servlet結束后自動發送消息)。

以上是我看了一點tomcat源碼然后瞎推理,對不對無所謂。。

當我們HttpServletResponse的包裝類弄完剩下的就好辦了。

//我們看下過濾器中的doFilter函數部分代碼就足夠了
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res= (HttpServletResponse) response;
     //我們剛剛做的包裝類在這里
        ShieldKeywordResponseWrapper skrw= new ShieldKeywordResponseWrapper(res);
        chain.doFilter(request, skrw);
        //在servlet處理完畢后我們開始做處理
        String result = skrw.getResult();
        //替換關鍵詞為*
        Properties p = new Properties();
        p.load(ShieldKeywords.class.getResourceAsStream("/keywords.properties"));
        Set<Entry<Object, Object>> se= p.entrySet();
        for(Entry<Object, Object> e:se){
            result = result.replace(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
        }
        // 輸出最終的結果
        PrintWriter out = response.getWriter();
        out.write(result);
        //以下兩句無作用,CharArrayWriter中為空函數,tomcat自己提供的OutputBuffer執行這兩句才有作用
        out.flush();
        out.close();
    }

最后看下keywords.properties文件的內容:

違法詞1=*
違法詞2=*

建議web.xml中過濾器配置時只映射響應文本數據的請求url,因有的請求是要獲取一個文件流,服務器HttpServletResponse響應時文本輸出流和字節流是沖突的,正常情況下兩者只可取一,不然會報錯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM