Filter
1.web中的過濾器:
當通路伺服器的資源時,過濾器可以将請求攔截下來,完成一些特殊的功能。
2.過濾器的作用:
一般用于完成通用的操作。如:登入驗證、統一編碼處理、敏感字元過濾…
3.簡單使用:
建立類,實作接口Filter
@WebFilter("/*")//通路所有資源之前,都會執行該過濾器
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterDemo1被執行了....");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
4.web.xml配置:
<filter>
<filter-name>demo1</filter-name>
<filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<!-- 攔截路徑 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
5.過濾器執行流程
(1)執行過濾器
(2)執行放行後的資源
(3)回來執行過濾器放行代碼下邊的代碼
6.過濾器生命周期方法
(1)init:在伺服器啟動後,會建立Filter對象,然後調用init方法。隻執行一次。用于加載資源
(2)doFilter:每一次請求被攔截資源時,會執行。執行多次
(3)destroy:在伺服器關閉後,Filter對象被銷毀。如果伺服器是正常關閉,則會執行destroy方法。隻執行一次。用于釋放資源
7.過濾器配置詳解:
攔截路徑配置
(1)具體資源路徑: /index.jsp 隻有通路index.jsp資源時,過濾器才會被執行
(2)攔截目錄: /user/* 通路/user下的所有資源時,過濾器都會被執行
(3)字尾名攔截:* *.jsp 通路所有字尾名為jsp資源時,過濾器都會被執行*
(4)攔截所有資源:/* 通路所有資源時,過濾器都會被執行
攔截方式配置:資源被通路的方式
(1)注解配置:
設定dispatcherTypes屬性:
REQUEST:預設值。浏覽器直接請求資源
FORWARD:轉發通路資源
INCLUDE:包含通路資源
ERROR:錯誤跳轉資源
ASYNC:異步通路資源
(2)web.xml配置:
設定<dispatcher></dispatcher>标簽即可
8.過濾器鍊(配置多個過濾器)
執行順序:如果有兩個過濾器:過濾器1和過濾器2
1. 過濾器1
2. 過濾器2
3. 資源執行
4. 過濾器2
5. 過濾器1
過濾器先後順序問題:
1. 注解配置:按照類名的字元串比較規則比較,值小的先執行
* 如: AFilter 和 BFilter,AFilter就先執行了。
2. web.xml配置: <filter-mapping>誰定義在上邊,誰先執行
9.敏感詞彙過濾:(案例)
* 增強對象的功能:
* 設計模式:一些通用的解決固定問題的方式
1. 裝飾模式
2. 代理模式
* 概念:
1. 真實對象:被代理的對象
2. 代理對象:
3. 代理模式:代理對象代理真實對象,達到增強真實對象功能的目的
* 實作方式:
1. 靜态代理:有一個類檔案描述代理模式
2. 動态代理:在記憶體中形成代理類
* 實作步驟:
1. 代理對象和真實對象實作相同的接口
2. 代理對象 = Proxy.newProxyInstance();
3. 使用代理對象調用方法。
4. 增強方法
* 增強方式:
1. 增強參數清單
2. 增強傳回值類型
3. 增強方法體執行邏輯
//敏感詞彙過濾器
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.建立代理對象,增強getParameter方法
ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增強getParameter方法
//判斷是否是getParameter方法
if(method.getName().equals("getParameter")){
//增強傳回值
//擷取傳回值
String value = (String) method.invoke(req,args);
if(value != null){
for (String str : list) {
if(value.contains(str)){
value = value.replaceAll(str,"***");
}
}
}
return value;
}
//判斷方法名是否是 getParameterMap
//判斷方法名是否是 getParameterValue
return method.invoke(req,args);
}
});
//2.放行
chain.doFilter(proxy_req, resp);
}
private List<String> list = new ArrayList<String>();//敏感詞彙集合
public void init(FilterConfig config) throws ServletException {
try{
//1.擷取檔案真實路徑
ServletContext servletContext = config.getServletContext();
String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感詞彙.txt");
//2.讀取檔案
BufferedReader br = new BufferedReader(new FileReader(realPath));
//3.将檔案的每一行資料添加到list中
String line = null;
while((line = br.readLine())!=null){
list.add(line);
}
br.close();
System.out.println(list);
}catch (Exception e){
e.printStackTrace();
}
}
public void destroy() {
}
}
Listener:監聽器
1.監聽機制:
* 事件 :一件事情
* 事件源 :事件發生的地方
* 監聽器 :一個對象
* 注冊監聽:将事件、事件源、監聽器綁定在一起。 當事件源上發生某個事件後,執行監聽器代碼
2.ServletContextListener:
監聽ServletContext對象的建立和銷毀
* 方法:
* void contextDestroyed(ServletContextEvent sce) :ServletContext對象被銷毀之前會調用該方法
* void contextInitialized(ServletContextEvent sce) :ServletContext對象建立後會調用該方法
* 步驟:
1. 定義一個類,實作ServletContextListener接口
2. 複寫方法
3. 配置
1. web.xml
<listener>
<listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class>
</listener>
* 指定初始化參數<context-param>
2.注解方式:
@WebListener
3.監聽器的入門:
在伺服器開啟時建立對象,關閉時被破壞:
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.FileInputStream;
@WebListener
public class ContextLoaderListener implements ServletContextListener {
/**
* 監聽ServletContext對象建立的。ServletContext對象伺服器啟動後自動建立。
*
* 在伺服器啟動後自動調用
* @param servletContextEvent
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//加載資源檔案
//1.擷取ServletContext對象
ServletContext servletContext = servletContextEvent.getServletContext();
//2.加載資源檔案
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//3.擷取真實路徑
String realPath = servletContext.getRealPath(contextConfigLocation);
//4.加載進記憶體
try{
FileInputStream fis = new FileInputStream(realPath);
System.out.println(fis);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("ServletContext對象被建立了。。。");
}
/**
* 在伺服器關閉後,ServletContext對象被銷毀。當伺服器正常關閉後該方法被調用
* @param servletContextEvent
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext對象被銷毀了。。。");
}
}