原創(chuàng)聲明:本文為作者原創(chuàng),未經(jīng)允許不得轉(zhuǎn)載,經(jīng)授權(quán)轉(zhuǎn)載需注明作者和出處
前面我們介紹過設(shè)置Servlet請求和響應(yīng)的字符編碼。當(dāng)時的做法是這樣:
直接在當(dāng)前Servlet接口上HttpServletRequest或者HttpServletResponse的編碼。照這么看,那么我們有多少個Servlet就得設(shè)置多少個類似的編碼。項目中只有一個兩個Servlet那還好說,如果項目中有幾百個呢?當(dāng)然,神奇的Servlet也想到了這個問題,于是它為我們提供了過濾器(Filter)這樣的解決方案。
Servlet的過濾器體現(xiàn)了面向切面(AOP)的編程思想。那么什么是面向切面呢?我們可以把客戶端和服務(wù)端之間數(shù)據(jù)傳輸過程比作是水管流水,這個傳輸?shù)倪B接就是水管,HttpServletRequest和HttpServletResponse就是水管里的水,往外或者往內(nèi)流,那么,我們的Filter就可以看做是把水管橫著切開,然后插入一個個大小不同網(wǎng)來攔截水中不同的東西。
簡單畫了一下我們客戶端和服務(wù)端數(shù)據(jù)交流的示意圖。如圖所示:
public class EncodingFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
和Servlet一樣,F(xiàn)liter也有自己的生命周期:
那么,別的不多講,有興趣的可以像試驗Servlet在每個方法內(nèi)打印一下,我們現(xiàn)在往doFilter()內(nèi)寫入處理字符編碼的業(yè)務(wù)邏輯:
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
arg0.setCharacterEncoding("UTF-8");//設(shè)置請求編碼
arg1.setCharacterEncoding("UTF-8");//設(shè)置響應(yīng)編碼
arg2.doFilter(arg0,arg1);//處理過的請求傳回原來的連接
}
其中FilterChain這個類主要是為了實(shí)現(xiàn)將處理過請求傳回原來的連接,相當(dāng)于給請求放行。因此我們可以利用這個移動端驗證登陸的過濾器,邏輯是用戶登陸之后服務(wù)器返回一個登陸的key并保存在緩存或者數(shù)據(jù)庫,移動端每次請求別的接口都需要在參數(shù)中駕駛證這個key,然后過濾器來驗證這個key在服務(wù)端是否存在,如果不存在,就不通過。
Filter寫好了,我們怎么用在Servlet上呢?配置web.xml,和Servlet的配置很像:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>com.dyg.Filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
寫完之后如圖:
這段配置和Servlet的配置很像,只不過url-pattern是配置過濾的路徑,這里”/“表示過濾所有的請求,按照圖中配置,如果將”/“改為”/test”則是過濾上,上面testServlet這個請求,該配置比較靈活,有可以做很多事情比如: