一、Filter過濾器
1.1 Filter過濾器的使用
- 這是過濾器介面的方法
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
default void destroy() {
}
}
- 一般情況下我們都在過濾器中新增公共的程式碼
- 例如我們經常設定字元編碼utf-8,為了減少重複的操作,我們直接在過濾器中設定即可。
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//在Filter物件第一次被建立的時候呼叫,並且只呼叫一次
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//doFilter()只要使用者傳送一次請求,則執行一次,傳送N次,則執行N次。在這個方法中編寫過濾規則
System.out.println("doFilter方法,前1");
//解決跨域問題
HttpServletResponse resp = (HttpServletResponse) servletResponse;
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Headers", "*");
resp.setHeader("Access-Control-Allow-Method", "*");
//執行下一個過濾器,如果說下一個不是過濾器,則會執行servlet
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("doFilter方法,後1");
}
@Override
public void destroy() {
//在Filter物件被釋放/銷燬之前呼叫,並且只呼叫一次
System.out.println("destroy方法");
}
}
-
init方法:在Filter物件第一次被建立的時候呼叫,並且只呼叫一次
-
doFilter方法:只要使用者傳送一次請求,則執行一次,傳送N次,則執行N次。在這個方法中編寫過濾規則
-
destroy方法:在Filter物件被釋放/銷燬之前呼叫,並且只呼叫一次
-
filterChain.doFilter(request, response);
執行下一個過濾器,如果下一個不是過濾器,則執行Servlet
目標Servlet是否執行取決於兩個條件:
- 過濾器中是否編寫了
filterChain.doFilter(request, response);
- 使用者發的請求路徑是否和Servlet的請求路徑一致
注意:
- Filter的優先順序天生就比Servlet高
- 使用@WebFilter的時候,Filter執行順序根據類名順序執行。
- Filter的生命週期與Servlet一樣,但是Filter會在伺服器啟動的時候就預設建立物件,而Servlet卻需要配置才可以。
- 如果在web.xml中配置兩個或者多個過濾器時,執行順序根據
<filter-mapping>
的先後。
1.2 Filter的責任鏈設計模式
- 我們先來看一下兩個過濾器的執行過程是什麼樣的
- Filter過濾器的doFilter方法,執行順序遵循的是棧結構,但是過濾器本身的生命週期就和佇列差不多吧。
- 其實doFilter方法,就是一種責任鏈設計模式!
//模仿棧
//模仿Filter設計模式
//缺點:在編譯階段已經完全確定了呼叫關係
//如果想要改變呼叫順序,必須要修改java程式碼
//違背了OCP原則(開閉原則)
public class Test {
public static void main(String[] args) {
System.out.println("main方法執行");
m1();
System.out.println("main執行完畢");
}
public static void m1() {
System.out.println("m1方法執行");
m2();
System.out.println("m1執行完畢");
}
public static void m2() {
System.out.println("m2方法執行");
m3();
System.out.println("m2執行完畢");
}
public static void m3() {
System.out.println("目標正在執行中");
}
}
- 這是執行的結果,是不是和Filter一樣~~~?
二、Listener監聽器
- 監聽器顧名思義:起到了監聽的作用,我想大家在javaGUI部分也瞭解過吧。
- 監聽器可以監測我們網站時時的線上人數等等
- 監聽器加上@WebListener註解或者在web.xml中配置一下即可,並不需要我們程式設計師去呼叫
- 下面是一個session監聽器
@WebListener
public class MyListener01 implements HttpSessionAttributeListener {
//監聽session行為的監聽器
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("add");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("removed");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("replaced");
}
}
- 下面是監聽整個Servlet生命週期的監聽器
@WebListener
public class MyListener implements ServletContextListener {
//監聽整個servlet生命週期的監聽器
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed");
}
}
- 感覺用途不是特別多,我瞭解的也比較少,就先介紹這麼多,感謝你的認真閱讀?
三、結尾
- 對於Tomcat的Servlet內容就總結這麼多,若想深入學習等待後續更新。
- 我將會繼續更新關於Java方向的學習知識,感興趣的小夥伴可以關注一下。
- 文章寫得比較走心,用了很長時間,絕對不是copy過來的!
- 尊重每一位學習知識的人,同時也尊重每一位分享知識的人。
- ?你的點贊與關注,是我努力前行的無限動力。?