學完JavaWeb階段有一段時間了,在進入框架學習之前,把JavaWeb三大組件做個總結記錄,為框架學習鋪點基礎.
一、什么是JavaWeb三大組件?
Servlet,Listener,Filter.它們在JavaWeb開發中分別提供不同的功能.
二、三大組件介紹
1、Servlet
1.1 servlet介紹
廣義上說,servlet是運行在web服務器或應用服務器的程序,用來處理客戶端請求的動態資源.Servlet = Service + Applet,表示小服務程序。狹義上來說,狹義的Servlet是指Java語言實現的一個接口,該接口有一個實現類為GenericServlet,該實現類有一個子類為HttpServlet,而我們實際開發中用的比較多的,就是我們通過根據具體的業務需求而繼承HttpServlet來創建的servlet.
1.2 創建servlet
通常來說,創建servlet有三種方式:實現Servlet接口,繼承GenericServlet類,繼承HttpServlet類.通常最后一種用的比較多,在開發中,可以自己手動地創建servlet,但是要記得配置web.xml(web2.5下).但是通常還是借助eclipse等編輯器快速創建servlet即可.
1.3 servlet的配置
簡單說就是web2.5的項目中,在web.xml配置文件中的設置修改.在eclipse中,該配置文件的位置是在WebContent/WEB-INF中
1
2
3
4
5
6
7
8
9
10
|
<
servlet
>
<
description
></
description
>
<
display-name
>servlet名稱</
display-name
>
<
servlet-name
>servlet名稱</
servlet-name
>
<
servlet-class
>servlet的全限定名,即包含了包名了的</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>servlet名稱</
servlet-name
>
<
url-pattern
>匹配路徑,例如/addServlet</
url-pattern
>
</
servlet-mapping
>
|
如果是通過eclipse快速創建的servlet,則web.xml會自動生成以上信息,自己只需要手動地按需求改一下匹配路徑就好了,當然不改也沒關系.關於這個匹配路徑,有幾點要注意下,一個是servlet中可以有多條匹配路徑與之對應,意思就是說 <url-pattern>匹配路徑,例如/addServlet</url-pattern> 這行代碼,可以多寫幾行,里面的匹配路徑可以為多個.到時候無論訪問哪一個路徑,都是會跳轉到該servlet的.另外一個就是匹配問題.這里面涉及到完全匹配,目錄匹配以及擴展名匹配.這其中完全匹配的優先級最高.需要注意⚠️的是,如果自己手動刪除了一個servlet,則需要到web.xml中手動刪除相對應的servlet的配置信息,這一步別忘了.
1.4 Servlet的生命周期
當我們談論Servlet時,我們實際上使用的是servlet對象,那么這個對象是什么時候創建和銷毀的.這個就是servlet的生命周期.簡單來說,Servlet的生命周期可被定義為從創建到毀滅的整個過程.參看以下:
- Servlet 通過調用 init () 方法進行初始化。
1
|
void init(ServletConfig)
|
servlet的初始化方法,只在創建servlet實例時候調用一次,Servlet是單例的,整個服務器就只創建一個同類型Servlet,servlet可以在第一次接受請求時被創建,也可以在服務器啟動時就被創建.這個時間點的設置,需要在web.xml的<servlet>中添加一條配置信息 < load-on-startup>5< /load-on-startup>,當值為0或者大於0時,表示容器在應用啟動時就加載這個servlet,當是一個負數時或者沒有指定時,則指示容器在該servlet被請求時才加載。
- Servlet 調用 service() 方法來處理客戶端的請求。
1
|
void service(ServletRequest,ServletResponse)
|
servlet的處理請求方法,在servle被請求時,會被馬上調用,每處理一次請求,就會被調用一次。ServletRequest類為請求類,ServletResponse類為響應類
- Servlet 通過調用 destroy() 方法終止(結束)。
1
|
void destory()
|
- 最后,Servlet 是由 JVM 的垃圾回收器進行垃圾回收的。
2、Filter
2.1 filter簡介
filer是javaweb中的過濾器,它與servlet一樣,也有三個生命周期方法,同時在web.xml的配置也差不多.但是兩者的主要功能不同,servlet負責處理請求,filter負責攔截請求和放行.可以實現Url級別的權限訪問,敏感詞匯過濾,解決編碼問題等等.
2.2 filter實現原理
Filter接口中有一個doFilter方法,當我們編寫好Filter,並配置對哪個web資源進行攔截后,WEB服務器每次在調用web資源的service方法之前,都會先調用一下filter的doFilter方法,因此,在該方法內編寫代碼可達到如下目的:
- 調用目標資源之前,讓一段代碼執行。
- 是否調用目標資源(即是否讓用戶訪問web資源)。
- 調用目標資源之后,讓一段代碼執行。
web服務器在調用doFilter方法時,會傳遞一個filterChain對象進來,filterChain對象是filter接口中最重要的一個對象,它也提供了一個doFilter方法,我們可以根據需求決定是否調用此方法,調用該方法,則web服務器就會調用web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。
2.3 filter實現步驟
- 編寫java類實現Filter接口,並實現其doFilter方法。
- 在 web.xml 文件中使用<filter>和<filter-mapping>元素對編寫的filter類進行注冊,並設置它所能攔截的資源。
范例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package
com.test.web.filter;
import
java.io.IOException;
import
javax.servlet.Filter;
import
javax.servlet.FilterChain;
import
javax.servlet.FilterConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletResponse;
public
class
FilterDemo01
implements
Filter {
@Override
public
void
init(FilterConfig filterConfig)
throws
ServletException {
System.out.println(
"----過濾器初始化----"
);
}
@Override
public
void
doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws
IOException, ServletException {
//對request和response進行一些預處理
request.setCharacterEncoding(
"UTF-8"
);
response.setContentType(
"text/html;charset=UTF-8"
);
System.out.println(
"Filter執行前"
);
chain.doFilter(request, response);
//放行
System.out.println(
"Filter執行后"
);
}
@Override
public
void
destroy() {
System.out.println(
"----過濾器銷毀----"
);
}
}
|
重要的一步,在web.xml中配置攔截規則
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?
xml
version="1.0" encoding="UTF-8"?>
<!--配置過濾器-->
<
filter
>
<
filter-name
>FilterDemo01</
filter-name
>
<
filter-class
>me.gacl.web.filter.FilterDemo01</
filter-class
>
</
filter
>
<!--映射過濾器-->
<
filter-mapping
>
<
filter-name
>FilterDemo01</
filter-name
>
<!--“/*”表示攔截所有的請求 -->
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
</
web-app
>
|
2.4 filter的四種攔截方式
REQUEST:直接訪問目標資源時執行過濾器。包括:在地址欄中直接訪問、表單提交、超鏈接、重定向,只要在地址欄中可以看到目標資源的路徑,就是REQUEST;
FORWARD:轉發訪問執行過濾器。包括RequestDispatcher#forward()方法、<jsp:forward>標簽都是轉發訪問;
INCLUDE:包含訪問執行過濾器。包括RequestDispatcher#include()方法、<jsp:include>標簽都是包含訪問;
ERROR:當目標資源在web.xml中配置為<error-page>中時,出現異常后,轉發到目標資源時,會執行過濾器。
3、Listener(主要是javaWeb中的監聽器)
3.1 監聽器簡介
監聽器就是一個實現了特定接口的java類,這個java類用來監聽另外一個java類的方法調用或者屬性改變,當被監聽的對象發生上述事件后,監聽器的某個方法就會立即執行.這里就涉及幾個相關概念:
事件源:被監聽的對象
事件:就是事件源的改變,一旦發生變化,事件就會傳遞給監聽器對象,監聽器的對應方法就會執行
監聽器:監聽的對象
綁定監聽器:在事件上綁定監聽器
3.2監聽器的分類
在servlet的規范中定義了多種類型的監聽器,主要用來監聽ServletContext,HttpSession,ServletReques三個域對象.按照功能划分,可以分成三類:
- 一類:監聽三個域對象的創建和銷毀的監聽器
- 二類:監聽三個域對象的屬性變更的監聽器(xxxAttribute())
- 三類:監聽HttpSession對象中的JavaBean的狀態的改變.(綁定,解除綁定,鈍化,活化)
三、拓展
1、servlet是不是單例設計模式?
servlet並不是單例設計模式,如果有多個Url映射到同一個servlet時,就會出現多個實例.
雖然 Servlet 在多數情況下只有一個實例。但它並不是單例設計模式,即不是真正的單例。
2、serlvet線程安全問題?
基於 JVM 對多線程的支持,這樣可以提高代碼的執行效率。 不需要為每一個請求都要單獨創建/銷毀 Servlet(執行 init(), desdroy() )。
同一段代碼可以在同一時間被多個請求同時執行。 Servlet 是普通的 Java 類,因此沒有對其做線程安全的處理