目錄
一、Filter過濾器的使用
【1】Filter技術概述
Filter技術,即過濾器技術,是Servlet三大核心技術之一,主要用於攔截請求進行過濾操作,是實現例如權限控制、全站亂碼解決、壓縮響應等功能的基礎,是web開發中最實用的技術之一。
【2】Filter訪問機制
過濾器可以配置多個,多個過濾器之前採用責任鏈模式,依次進行攔截。只有所有過濾器都通過,纔可以訪問到最終的資源。
如果是在web.xml中進行配置,通過<filter>和<filter-mapping>標籤實現配置。<filter-mapping>用來設置此外過濾器的虛擬路徑,只有符合過濾的虛擬路徑,纔會被過濾器攔截。不符合將不會被攔截,此外攔截的順序是通過標籤<filter-mapping>的上下順序進行過濾。
如果是通過WebFilter()註解方式進行配置,可以使用filterName屬性來指定filter的名稱,可以使用value屬性或者urlPatterns屬性來指定Filter過濾的虛擬路徑。只有符合過濾的虛擬路徑,纔會被過濾器攔截。不符合將不會被攔截,此外攔截的規則是通過屬性filterName的字母順序進行過濾。
【3】Filter的生命週期
在tomcat服務器啓動後加載當前web應用時,filter會創建一個對象駐留在內存當中,在創建對象之後,立刻調用init方法完成初始化的操作。每次過濾器攔截請求或響應,都會導致它身上的doFilter方法執行,在doFilter方法中可以選擇是否放行,如果放行在放行代碼前後可以添加額外操作。當tomcat服務器關閉,在服務器關閉之前,filter對象銷燬,對象銷燬之前會自動調用destroy方法完成善後的操作。
補充:
【1】關於doFilter方法,每次過濾器攔截請求和響應之後,都會執行,請求過來時,會執行chain.doFilter(req, resp);語句前面的內容,響應回來之後,會執行chain.doFilter(req, resp);語句後面的內容。這點有點像請求轉發執行的過程。
【2】關於責任鏈,在一個web應用中可以配置多個過濾器,只有請求響應都通過這些過濾器,纔可以到達對應的資源身上,這些過濾器組成的鏈稱爲過濾器鏈。這些過濾器鏈稱之爲過濾器的責任鏈模式。
【4】使用過濾器處理中文亂碼問題
使用服務器(tomcat7)及其以下版本,默認使用的是iso8859-1字符集,因爲iso8859-1編碼沒有中文,所以會產生亂碼。
如果頁面使用的是POST請求提交方式,我們可以使用request.setCharacterEncoding("utf-8");設置編碼字符集爲utf-8。
如果頁面使用的是GET請求提交方式,我們可以使用new String(request.getParameter("username").getBytes("iso8859-1"),"utf-8");方式處理亂碼。
如果我們使用的處理POST處理方式則不能處理GET請求方式的亂碼,但如果我們使用GET請求方式,卻可以處理POST請求方式。所以使用GET請求方式進行處理。但如果使用GET請求方式,則不容易獲取,需要處理的參數。所以,我們可以對getParameters()之類的方法進行增強,通過裝飾者模式進行增強方法。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
class MyHttpServletRequest extends HttpServletRequestWrapper {
private String encode;
public MyHttpServletRequest(HttpServletRequest request, String encode) {
super(request);
this.encode = encode;
}
//重寫的方法
/**
* 返回一個經過亂碼處理後的map對象
* @return
*/
@Override
public Map<String, String[]> getParameterMap() {
//獲取原有的map值,依次作出亂碼處理,處理後將值放入到新map中,並返回
Map<String, String[]> map = super.getParameterMap();
//創建新的map,用於存放處理好的map參數
Map<String, String[]> rmap = new HashMap<String, String[]>();
try {
//遍歷map
for (Map.Entry<String, String[]> entry: map.entrySet()) {
String key = entry.getKey();
String[] values = entry.getValue();
String[] rvalues = new String[values.length];
for (int i = 0; i < values.length; i++) {
rvalues[i] = new String(values[i].getBytes("iso8859-1"),encode);
}
//將亂碼處理後的數組放入到新map中
rmap.put(key,rvalues);
}
return rmap;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> map = getParameterMap();
return map.get(name);
}
@Override
public String getParameter(String name) {
String[] values = getParameterValues(name);
//如果數組爲null,則返回null,否則將數組中的第一個元素作爲方法返回值使用
return values==null?null:values[0];
}
}
書寫一個自定義類,繼承HttpServletRequestWrapper 實現類,增強getParameterMap、getParameterValues、getParameter方法。
之所以繼承HttpServletRequestWrapper 類,是因爲HttpServletRequestWrapper 幫我們實現了ServletRequest與HttpServletRequest接口的方法。HttpServletRequest繼承ServletRequest接口,HttpServletRequestWrapper 實現HttpServletRequest接口。
在Filter類上配置註解爲@WebFilter(filterName = "EncodingFilter",value="/*")
在過濾器doFilter中書寫以下內容便可以對中文進行過濾。
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//請求亂碼處理
HttpServletRequest request = new MyHttpServletRequest((HttpServletRequest) req);
//響應亂碼處理
resp.setContentType("text/html;charset="+encode);
chain.doFilter(request, resp);
}
二、Listener監聽器的使用
【1】監聽器技術概述
Listener是Servlet三大技術之一。Servlet三大技術包含Filter、Listener、Servlet。
如果希望自己的網站收集一些必要的數據,可以通過Listener監聽器去監聽獲取。在某一個事件觸發監聽器之後,監聽器會執行對應的操作。
【2】監聽器的種類
1、監聽三大作用域創建和銷燬的監聽器
ServletContextListener | 監聽ServletContext域的創建銷燬 |
HttpSessionListener | 監聽Session域的創建銷燬 |
ServletRequestListener | 監聽request域的創建銷燬 |
2、監聽三大作用域中屬性變化的監聽器(創建、更新、銷燬)
ServletContextAttributeListener | 監聽ServletContext域中屬性的變化 |
HttpSessionAttributeListener | 監聽Session域中屬性的變化 |
ServletRequestAttributeListener | 監聽request域中屬性的變化 |
實現以上三個接口,可以獲得到三個域對象,從而獲取用戶的信息,參數,譬如響應頭,請求頭,url地址等等。
3、監聽JavaBean在Session域中狀態變化的監聽器
HttpSessionBindingListener | 監聽javabean在session域中添加和銷燬事件 |
HttpSessionActivationListener | 讓javabean自己感知到自己隨着session被鈍化和活化。 |
Javabean實現HttpSessionBindingListener和HttpSessionActivationListener接口,會重寫這兩個接口中的方法,HttpSessionBindingListener用於感知javabean在session域的變化。
HttpSessionActivationListener讓javabean自己感知到自己隨着session被鈍化和活化。
鈍化是指當服務器正常關閉時,還存活着的session 會隨着服務器的關閉被以文件(“SESSIONS.ser”)的形式存儲在tomcat 的work 目錄下。
活化是指當服務器再次正常開啓時,服務器會找到之前的“SESSIONS.ser” 文件,從中恢復之前保存起來的Session 對象。此時SESSIONS.ser這個文件會被消除。
想要隨着Session 被鈍化、活化的對象它的類必須實現Serializable 接口。關於序列化的問題,可參考https://blog.csdn.net/c17315377559/article/details/100044843