前言
到這裡我們對Java Web的學習也到尾聲了,本專欄關于Java Web的知識也是非常全的,如果有這方面的需求可以關注一下本專欄。
接下來我們來學習幾個輔助性質的技術,首先來學習過濾器。
目錄
- 前言
- 什麼是過濾器?
- 開發一個過濾器
- 過濾器的生命周期
- 過濾器參數化
- 設定過濾範圍
- 過濾鍊
- 結語
什麼是過濾器?
過濾器實際上就是對web資源,做一些
進行攔截
後再
處理
。
交給下一個過濾器或servlet處理
通常都是用來攔截request進行處理的,也可以對傳回的response進行攔截處理。
對于過濾器:
(1)過濾器(
Filter
)是J2EE Servlet模闆下的元件。
(2)Filter的作用是對
URL進行統一的攔截處理
。
(3)Filter通常用于
應用程式層面
進行全局處理。
大概流程圖如下:
![]()
【過濾器入門】學會使用過濾器,為你的web項目添磚加瓦前言什麼是過濾器?開發一個過濾器過濾器的生命周期過濾器參數化設定過濾範圍過濾鍊結語
開發一個過濾器
要隻要我們開發一個過濾器都需要經過一下三個步驟:
(1)任何過濾器都要實作
javax.servlet.Filter
接口。
(2)在Filter接口的
do Filter()
方法中編寫過濾器的功能代碼。
(3)在
中對過濾器進行配置,說明攔截URL的範圍。
web.xml
接下來我們就來示範開發一個簡單的過濾器。
首先建立寫一個過濾器先實作
Filter
接口,然後重寫裡面的
do Filter()
方法。
我們第一個過濾器:
public class MyFirstFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("過濾器已生效");
chain.doFilter(request, response);
}
}
在web.xml中進行配置
(1)filter标簽用于說明哪個類是過濾器,并在應用啟動時自動加載.
(2)filter-mapping标簽用于說明過濾器對URL應用的範圍,要點有二:
- filter-name 過濾器名稱與filter.filter-name保持一緻
- url-pattern 說明過濾器作用範圍,
/*代表對所有URL進行過濾
<!-- filter标簽用于說明哪個類是過濾器,并在應用啟動時自動加載 -->
<filter>
<filter-name>MyFirstFilter</filter-name>
<filter-class>com.imooc.filter.MyFirstFilter</filter-class>
</filter>
<!--
filter-mapping标簽用于說明過濾器對URL應用的範圍,要點有二:
1.filter-name 過濾器名稱與filter.filter-name保持一緻
2.url-pattern 說明過濾器作用範圍, /*代表對所有URL進行過濾
-->
<filter-mapping>
<filter-name>MyFirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我們再寫一個servlet進行測試:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html ; charset=utf-8");
response.getWriter().println("你好,世界!");
}
輸出:
在浏覽器對servlet進行通路
看控制台
說明我們在
do Filter()
中設定的處理語句成功生效了。
我們除了在web.xml中配置還可以使用注解形式配置,如:
@WebFilter(filterName="MyFirstFilter", urlPatterns="/*")
public class MyFirstFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("過濾器已生效");
chain.doFilter(request, response);
}
}
看起來是非常簡單的,也是配置成功了。
過濾器的生命周期
我們在實作Filter接口之後,其實需要重寫的方法有三個,如下:
public class MyFirstFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
這三個函數也構成了過濾器的生命周期。它們的作用分别是:
(1)
Filter.init()
:過濾器初始化工作。
(2)
Filter.doFilter()
:進行過濾處理。
(3)
:銷毀過濾器。
Filter.destroy()
![]()
【過濾器入門】學會使用過濾器,為你的web項目添磚加瓦前言什麼是過濾器?開發一個過濾器過濾器的生命周期過濾器參數化設定過濾範圍過濾鍊結語
我們可以把之前的案例中的過濾器進行更改,如下:
public class MyFirstFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("過濾器已被銷毀");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("過濾器已生效");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
System.out.println("過濾器初始化成功");
}
}
看一下過濾器的處理過程:
在啟動Tomcat之後,先是初始化成功,然後在通路url之後過濾器生效了。
最後在關閉Tomcat之後,顯示銷毀過濾器了。
過濾器的特征:
(1) 過濾器對象在Web應用且
啟動時被建立
(2)唯一的過濾器對象在并發環境中采用“
全局唯一
”提供服務
多線程
過濾器參數化
過濾器參數化分為兩部分:
(1)過濾器為了增強靈活性,允許配
置資訊放在web.xml
中。
(2)在web.xml中配置
<init-param>設定過濾器參數
接下來我們做一個字元集過濾器來進行示範:
Web輸出是中文的話會出現中文亂碼問題,對于解決中文亂碼問題我們有以下幾個辦法:
(1)GET請求:在中增加
servlet.xml
URIEncoding = "UTF-8"
。
(2)POST請求:使用
(3)響應:
request.setCharacterEncoding("UTF-7");
response.setContentType("text/html;charset=UTF-8");
如果我們做的是個大的項目的話我們就需要給多個Servlet去添加這些東西,其實我們隻需要添加一個過濾器提前去解決這些問題就行了。不必去一個一個添加處理。
我們寫一個字元集過濾器,但是有時根據使用者不同我們使用的字元集編碼又不是統一的,需要經常進行更改,如果直接在過濾器中進行更改的話,我們每一次更改都需要整個項目重新進行編譯處理,重新釋出。
這樣十分麻煩,我們直接在web.xml中把字元集設定成參數,在web.xml中更改,由于這是一個解釋型語言,是以不需要重新編譯就很友善。
如下:
public class CharacterEncodingFilter implements Filter {
//設定所用的字元集編碼,值通過過濾器擷取
private String encoding;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest)request;
req.setCharacterEncoding(encoding);
HttpServletResponse res = (HttpServletResponse)response;
res.setContentType("text/html; charset = " + encoding);
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
encoding = filterConfig.getInitParameter("encoding");
System.out.println("encoding:" + encoding);
}
}
在web.xml中進行配置并且設定參數:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.imooc.filter.CharacterEncodingFilter</filter-class>
<!-- 設定參數-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
非常簡單,但是非常實用。
設定過濾範圍
在前面簡略的提到了
url-pattern
說明過濾器作用範圍,
/*代表對所有URL進行過濾
。接下來我們就具體來學習在url-pattern标簽中設定過濾器生效的範圍。
url-pattern常用寫法
(1):執行資源
/index.jsp
精準
比對
(2)
:以
/servlet/*
字首
進行模式比對
(3)
:以
*.jsp
進行模式比對
字尾
例如
*.jsp
,就是把url字尾為
*.jsp
的所有url進行攔截下來通過所綁定的這個過濾器處理。其他類同!
過濾鍊
我們在寫一個web項目的時候,使用的到過濾器通常不止一個,這些多個過濾器就構成了一個過濾鍊,如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI2EzX4xSZz91ZsAzNfRHLGZkRGZkRfJ3bs92YsAjMfVmepNHL90TU2pVZlpGNTVmdaVWZ2pVZtgVQClGVF5UMR9Fd4VGdsATNfd3bkFGazxSUhxGatJGbwhFT1Y0Mk9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2kzNxQzYkVTOhJWZwUDN4EGO0QTNmZGZ5QDZ0kTZiF2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
我們在開發過濾鍊的時候需要注意:
(1)每一個過濾器應具有單獨職能。
(2)過濾器的執行順序以
中
web.xml
<filter-mapping>
的順序為準。
(3)調用
将請求向後傳遞。
chain.doFilter()
尤其注意
chain.doFilter()
,我們之前在doFilter方法中的最後一步都是
chain.doFilter(request, response)
,就是代表将請求傳向下一個過濾器或者servlet。
結語
過濾器内容比較少,但是過濾器比較常用是以還是要多多了解練習!
本專欄持續更新中…