過濾器的作用不論是在前端和后端都存在非常重要的作用,但是其實現(xiàn)還是非常簡單的。原理圖:
[圖片上傳失敗...(image-9de27e-1551666962606)]
在開發(fā)中過濾器有有一個什么樣的角色?
在實際開發(fā)與前端對接時,前端開發(fā)者傳輸過來的數(shù)據(jù)一般是UTF-8格式的,而JSP中卻不是這種默認(rèn)格式。因此,我們需要將數(shù)據(jù)和頁面格式相匹配。
但是,后端服務(wù)中不可能說只有一個控制器。在View與Controller的交互中,往往非常多的請求服務(wù)頁面,因此如果每個頁面都去設(shè)置一個設(shè)置編碼語句,不久造成不必要的代碼重復(fù)了嗎?因此過濾器在其中扮演著規(guī)則的角色。我制定的規(guī)則,在我過濾的范圍內(nèi)都需要執(zhí)行。
過濾器API
只需要實現(xiàn)Filter接口,和它的三個生命周期方法就能夠使用了
其中init()和destory()和Servlet一樣的作用。其中的精髓還是在于doFilter方法,它有三個參數(shù)ServletRequest,ServletResponse,FilterChain,前面兩個都很熟悉,而FilterChain非常陌生那么它是什么呢?
FilterChain????
我們看一下它的源碼:
public interface FilterChain {
void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws java.io.IOException, javax.servlet.ServletException;
}
看的出,它是一個interface接口。里面依舊是兩個參數(shù)ServletRequest,ServletResponse。
其實在一個企業(yè)級項目中往往存在非常多的過濾器,比如在過濾編碼的同時,還需要過濾登錄狀態(tài),然后也需要過濾一些關(guān)鍵字......等等非常多過濾需求,一層一層過濾下去
[圖片上傳失敗...(image-403c27-1551666962606)]
可以看的到,第一個過濾器執(zhí)行了,如果碰到FilterChain的話會執(zhí)行第二個過濾器,當(dāng)執(zhí)行完所有過濾操作后,從內(nèi)向外依次關(guān)閉。
Filter的配置
有兩種方法可以配置Filter,第一種是web.xml配置路徑,范圍,默認(rèn)值,
<filter>
<filter-name>FilterDemo1</filter-name>
<filter-class>FilterDemo1</filter-class>
<init-param>
<param-name>word_file</param-name>
<param-value>/WEB-INF/word.txt</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FilterDemo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-name>子元素用于設(shè)置filter的注冊名稱。**該值必須是在元素中聲明過的過濾器的名字
<url-pattern>設(shè)置 filter 所攔截的請求路徑(過濾器關(guān)聯(lián)的URL樣式)**
<servlet-name>指定過濾器所攔截的Servlet名稱**。
<dispatcher>指定過濾器所攔截的資源被 Servlet 容器調(diào)用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認(rèn)REQUEST。用戶可以設(shè)置多個
<dispatcher>子元素用來指定 Filter 對資源的多種調(diào)用方式進(jìn)行攔截。
第二種是通過注解:
@WebFilter(filterName = "FilterDemo1",urlPatterns = "/*")
過濾器是一個非常常見的東西,但是用處也是非常大的。