JavaWeb:Servlet技術
JavaWeb:Servlet技術
快速開始
Servlet是什麽
Java Servlet 是運行在 Web 服務器或應用服務器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務器上的數據庫或應用程序之間的中間層。使用 Servlet,您可以收集來自網頁表單的用戶輸入,呈現來自數據庫或者其他源的記錄,還可以動態創建網頁。
Servlet在Web應用程序中的位置:
Servlet的任務
Servlet 執行以下主要任務:
- 讀取客戶端(瀏覽器)發送的顯式的數據。這包括網頁上的 HTML 表單,或者也可以是來自 applet 或自定義的 HTTP 客戶端程序的表單。
- 讀取客戶端(瀏覽器)發送的隱式的 HTTP 請求數據。這包括 cookies、媒體類型和瀏覽器能理解的壓縮格式等等。
- 處理數據並生成結果。這個過程可能需要訪問數據庫,執行 RMI 或 CORBA 調用,調用 Web 服務,或者直接計算得出對應的響應。
- 發送顯式的數據(即文檔)到客戶端(瀏覽器)。該文檔的格式可以是多種多樣的,包括文本文件(HTML 或 XML)、二進制文件(GIF 圖像)、Excel 等。
- 發送隱式的 HTTP 響應到客戶端(瀏覽器)。這包括告訴瀏覽器或其他客戶端被返回的文檔類型(例如 HTML),設置 cookies 和緩存參數,以及其他類似的任務。
Servlet環境配置
下載Tomcat服務器
官網地址:https://tomcat.apache.org/download-80.cgi
將Web開發包加入環境變量
創建我們的第一個Servlet
我們繼承了HTTPServlet,實現我們自己的Servlet:
一個特殊的類:
ServletContext:Servlet上下文對象,Servlet通過訪問該對象來訪問容器為當前Web應用提供的各種支持。
Servlet的聲明周期
- 第一個到達服務器的 HTTP 請求被委派到 Servlet 容器。
- Servlet 容器在調用 service() 方法之前加載 Servlet。
- 然後 Servlet 容器處理由多個線程產生的多個請求,每個線程執行一個單一的 Servlet 實例的 service() 方法。
- init:負責初始化Servlet對象,容器在創建好Servlet對象後,就會調用該方法。
- init 方法被設計成只調用一次。它在第一次創建 Servlet 時被調用,在後續每次用戶請求時不再調用。
- Servlet 創建於用戶第一次調用對應於該 Servlet 的 URL 時,但是您也可以指定 Servlet 在服務器第一次啟動時被加載。
- 當用戶調用一個 Servlet 時,就會創建一個 Servlet 實例,每一個用戶請求都會產生一個新的線程,適當的時候移交給 doGet 或 doPost 方法。init() 方法簡單地創建或加載一些數據,這些數據將被用於 Servlet 的整個生命周期。
- destory:負責釋放Servlet對象占用的資源,當Servlet對象結束生命周期時,容器就會調用此方法。
- destroy() 方法只會被調用一次,在 Servlet 生命周期結束時被調用。destroy() 方法可以讓您的 Servlet 關閉數據庫連接、停止後臺線程、把 Cookie 列表或點擊計數器寫入到磁盤,並執行其他類似的清理活動。
- destroy方法在容器移除servlet 時執行,同樣只執行一次。這個方法會在所有的線程的service()方法執行完成或者超時後執行,調用這個方法後,容器不會再調用這個servlet的方法,也就是說容器不再把請求發送給這個servlet。這個方法給servlet釋放占用的資源的機會,通常用來執行一些清理任務.
Servlet與Tomcat的關系
這個提問的最大一個bug,就是以為servlet是很復雜的東西,事實上,servlet就是一個Java接口,interface! 打開idea,ctrl + shift + n,搜索servlet,就可以看到是一個只有5個方法的interface!
所以,提問中說的網絡協議、http什麽的,servlet根本不管!也管不著!
那servlet是幹嘛的?很簡單,接口的作用是什麽?規範唄!
servlet接口定義的是一套處理網絡請求的規範,所有實現servlet的類,都需要實現它那五個方法,其中最主要的是兩個生命周期方法 init()和destroy(),還有一個處理請求的service(),也就是說,所有實現servlet接口的類,或者說,所有想要處理網絡請求的類,都需要回答這三個問題:
- 你初始化時要做什麽
- 你銷毀時要做什麽
- 你接受到請求時要做什麽
這是Java給的一種規範!就像阿西莫夫的機器人三大定律、行屍走肉裏Rick的那三個問題一樣,規範!
servlet是一個規範,那實現了servlet的類,就能處理請求了嗎?
答案是,不能。
你可以隨便谷歌一個servlet的hello world教程,裏面都會讓你寫一個servlet,相信我,你從來不會在servlet中寫什麽監聽8080端口的代碼,servlet不會直接和客戶端打交道!
那請求怎麽來到servlet呢?答案是servlet容器,比如我們最常用的tomcat,同樣,你可以隨便谷歌一個servlet的hello world教程,裏面肯定會讓你把servlet部署到一個容器中,不然你的servlet壓根不會起作用。
Tomcat才是與客戶端直接打交道的家夥,他監聽了端口,請求過來後,根據url等信息,確定要將請求交給哪個servlet去處理,然後調用那個servlet的service方法,service方法返回一個response對象,tomcat再把這個response返回給客戶端。
接收請求和做出響應
Http請求的重要頭信息
頭信息 | 描述 |
---|---|
Accept | 這個頭信息指定瀏覽器或其他客戶端可以處理的 MIME 類型。值 image/png 或 image/jpeg 是最常見的兩種可能值。 |
Accept-Charset | 這個頭信息指定瀏覽器可以用來顯示信息的字符集。例如 ISO-8859-1。 |
Accept-Encoding | 這個頭信息指定瀏覽器知道如何處理的編碼類型。值 gzip 或 compress 是最常見的兩種可能值。 |
Accept-Language | 這個頭信息指定客戶端的首選語言,在這種情況下,Servlet 會產生多種語言的結果。例如,en、en-us、ru 等。 |
Authorization | 這個頭信息用於客戶端在訪問受密碼保護的網頁時識別自己的身份。 |
Connection | 這個頭信息指示客戶端是否可以處理持久 HTTP 連接。持久連接允許客戶端或其他瀏覽器通過單個請求來檢索多個文件。值 Keep-Alive 意味著使用了持續連接。 |
Content-Length | 這個頭信息只適用於 POST 請求,並給出 POST 數據的大小(以字節為單位)。 |
Cookie | 這個頭信息把之前發送到瀏覽器的 cookies 返回到服務器。 |
Host | 這個頭信息指定原始的 URL 中的主機和端口。 |
If-Modified-Since | 這個頭信息表示只有當頁面在指定的日期後已更改時,客戶端想要的頁面。如果沒有新的結果可以使用,服務器會發送一個 304 代碼,表示 Not Modified 頭信息。 |
If-Unmodified-Since | 這個頭信息是 If-Modified-Since 的對立面,它指定只有當文檔早於指定日期時,操作才會成功。 |
Referer | 這個頭信息指示所指向的 Web 頁的 URL。例如,如果您在網頁 1,點擊一個鏈接到網頁 2,當瀏覽器請求網頁 2 時,網頁 1 的 URL 就會包含在 Referer 頭信息中。 |
User-Agent | 這個頭信息識別發出請求的瀏覽器或其他客戶端,並可以向不同類型的瀏覽器返回不同的內容。 |
瀏覽器Http請求
下面的方法可用在 Servlet 程序中讀取 HTTP 頭。這些方法通過 HttpServletRequest 對象可用。
序號 | 方法 & 描述 |
---|---|
1 | Cookie[] getCookies() 返回一個數組,包含客戶端發送該請求的所有的 Cookie 對象。 |
2 | Enumeration getAttributeNames() 返回一個枚舉,包含提供給該請求可用的屬性名稱。 |
3 | Enumeration getHeaderNames() 返回一個枚舉,包含在該請求中包含的所有的頭名。 |
4 | Enumeration getParameterNames() 返回一個 String 對象的枚舉,包含在該請求中包含的參數的名稱。 |
5 | HttpSession getSession() 返回與該請求關聯的當前 session 會話,或者如果請求沒有 session 會話,則創建一個。 |
6 | HttpSession getSession(boolean create) 返回與該請求關聯的當前 HttpSession,或者如果沒有當前會話,且創建是真的,則返回一個新的 session 會話。 |
7 | Locale getLocale() 基於 Accept-Language 頭,返回客戶端接受內容的首選的區域設置。 |
8 | Object getAttribute(String name) 以對象形式返回已命名屬性的值,如果沒有給定名稱的屬性存在,則返回 null。 |
9 | ServletInputStream getInputStream() 使用 ServletInputStream,以二進制數據形式檢索請求的主體。 |
10 | String getAuthType() 返回用於保護 Servlet 的身份驗證方案的名稱,例如,"BASIC" 或 "SSL",如果JSP沒有受到保護則返回 null。 |
11 | String getCharacterEncoding() 返回請求主體中使用的字符編碼的名稱。 |
12 | String getContentType() 返回請求主體的 MIME 類型,如果不知道類型則返回 null。 |
13 | String getContextPath() 返回指示請求上下文的請求 URI 部分。 |
14 | String getHeader(String name) 以字符串形式返回指定的請求頭的值。 |
15 | String getMethod() 返回請求的 HTTP 方法的名稱,例如,GET、POST 或 PUT。 |
16 | String getParameter(String name) 以字符串形式返回請求參數的值,或者如果參數不存在則返回 null。 |
17 | String getPathInfo() 當請求發出時,返回與客戶端發送的 URL 相關的任何額外的路徑信息。 |
18 | String getProtocol() 返回請求協議的名稱和版本。 |
19 | String getQueryString() 返回包含在路徑後的請求 URL 中的查詢字符串。 |
20 | String getRemoteAddr() 返回發送請求的客戶端的互聯網協議(IP)地址。 |
21 | String getRemoteHost() 返回發送請求的客戶端的完全限定名稱。 |
22 | String getRemoteUser() 如果用戶已通過身份驗證,則返回發出請求的登錄用戶,或者如果用戶未通過身份驗證,則返回 null。 |
23 | String getRequestURI() 從協議名稱直到 HTTP 請求的第一行的查詢字符串中,返回該請求的 URL 的一部分。 |
24 | String getRequestedSessionId() 返回由客戶端指定的 session 會話 ID。 |
25 | String getServletPath() 返回調用 JSP 的請求的 URL 的一部分。 |
26 | String[] getParameterValues(String name) 返回一個字符串對象的數組,包含所有給定的請求參數的值,如果參數不存在則返回 null。 |
27 | boolean isSecure() 返回一個布爾值,指示請求是否使用安全通道,如 HTTPS。 |
28 | int getContentLength() 以字節為單位返回請求主體的長度,並提供輸入流,或者如果長度未知則返回 -1。 |
29 | int getIntHeader(String name) 返回指定的請求頭的值為一個 int 值。 |
30 | int getServerPort() 返回接收到這個請求的端口號。 |
31 | int getParameterMap() 將參數封裝成 Map 類型。 |
常見的Http響應報頭
頭信息 | 描述 |
---|---|
Allow | 這個頭信息指定服務器支持的請求方法(GET、POST 等)。 |
Cache-Control | 這個頭信息指定響應文檔在何種情況下可以安全地緩存。可能的值有:public、private或 no-cache 等。Public 意味著文檔是可緩存,Private 意味著文檔是單個用戶私用文檔,且只能存儲在私有(非共享)緩存中,no-cache 意味著文檔不應被緩存。 |
Connection | 這個頭信息指示瀏覽器是否使用持久 HTTP 連接。值 close 指示瀏覽器不使用持久 HTTP 連接,值 keep-alive 意味著使用持久連接。 |
Content-Disposition | 這個頭信息可以讓您請求瀏覽器要求用戶以給定名稱的文件把響應保存到磁盤。 |
Content-Encoding | 在傳輸過程中,這個頭信息指定頁面的編碼方式。 |
Content-Language | 這個頭信息表示文檔編寫所使用的語言。例如,en、en-us、ru 等。 |
Content-Length | 這個頭信息指示響應中的字節數。只有當瀏覽器使用持久(keep-alive)HTTP 連接時才需要這些信息。 |
Content-Type | 這個頭信息提供了響應文檔的 MIME(Multipurpose Internet Mail Extension)類型。 |
Expires | 這個頭信息指定內容過期的時間,在這之後內容不再被緩存。 |
Last-Modified | 這個頭信息指示文檔的最後修改時間。然後,客戶端可以緩存文件,並在以後的請求中通過 If-Modified-Since 請求頭信息提供一個日期。 |
Location | 這個頭信息應被包含在所有的帶有狀態碼的響應中。在 300s 內,這會通知瀏覽器文檔的地址。瀏覽器會自動重新連接到這個位置,並獲取新的文檔。 |
Refresh | 這個頭信息指定瀏覽器應該如何盡快請求更新的頁面。您可以指定頁面刷新的秒數。 |
Retry-After | 這個頭信息可以與 503(Service Unavailable 服務不可用)響應配合使用,這會告訴客戶端多久就可以重復它的請求。 |
Set-Cookie | 這個頭信息指定一個與頁面關聯的 cookie。 |
服務器Http響應
序號 | 方法 & 描述 |
---|---|
1 | String encodeRedirectURL(String url) 為 sendRedirect 方法中使用的指定的 URL 進行編碼,或者如果編碼不是必需的,則返回 URL 未改變。 |
2 | String encodeURL(String url) 對包含 session 會話 ID 的指定 URL 進行編碼,或者如果編碼不是必需的,則返回 URL 未改變。 |
3 | boolean containsHeader(String name) 返回一個布爾值,指示是否已經設置已命名的響應報頭。 |
4 | boolean isCommitted() 返回一個布爾值,指示響應是否已經提交。 |
5 | void addCookie(Cookie cookie) 把指定的 cookie 添加到響應。 |
6 | void addDateHeader(String name, long date) 添加一個帶有給定的名稱和日期值的響應報頭。 |
7 | void addHeader(String name, String value) 添加一個帶有給定的名稱和值的響應報頭。 |
8 | void addIntHeader(String name, int value) 添加一個帶有給定的名稱和整數值的響應報頭。 |
9 | void flushBuffer() 強制任何在緩沖區中的內容被寫入到客戶端。 |
10 | void reset() 清除緩沖區中存在的任何數據,包括狀態碼和頭。 |
11 | void resetBuffer() 清除響應中基礎緩沖區的內容,不清除狀態碼和頭。 |
12 | void sendError(int sc) 使用指定的狀態碼發送錯誤響應到客戶端,並清除緩沖區。 |
13 | void sendError(int sc, String msg) 使用指定的狀態發送錯誤響應到客戶端。 |
14 | void sendRedirect(String location) 使用指定的重定向位置 URL 發送臨時重定向響應到客戶端。 |
15 | void setBufferSize(int size) 為響應主體設置首選的緩沖區大小。 |
16 | void setCharacterEncoding(String charset) 設置被發送到客戶端的響應的字符編碼(MIME 字符集)例如,UTF-8。 |
17 | void setContentLength(int len) 設置在 HTTP Servlet 響應中的內容主體的長度,該方法設置 HTTP Content-Length 頭。 |
18 | void setContentType(String type) 如果響應還未被提交,設置被發送到客戶端的響應的內容類型。 |
19 | void setDateHeader(String name, long date) 設置一個帶有給定的名稱和日期值的響應報頭。 |
20 | void setHeader(String name, String value) 設置一個帶有給定的名稱和值的響應報頭。 |
21 | void setIntHeader(String name, int value) 設置一個帶有給定的名稱和整數值的響應報頭。 |
22 | void setLocale(Locale loc) 如果響應還未被提交,設置響應的區域。 |
23 | void setStatus(int sc) 為該響應設置狀態碼。 |
Http狀態碼
參見菜鳥教程:www.runoob.com/servlet/servlet-http-status-codes.html
創建Web項目
Web應用的目錄結構
– 應用程序根目錄
– |-- WEB-INF目錄:必須目錄
– |-- web.xml:Web應用部署描述文件,必須目錄
– |-- classes目錄:存放字節碼文件
– |-- lib目錄:存放第三方類庫文件
– |-- TLD文件:標簽庫描述文件
– |-- 其他靜態文件:HTML、CSS、JavaScript、圖片等
web.xml文件
web.xml文件是JavaWeb應用的XML格式的配置文件,存放於WEB-INF子目錄下。由開發人員編寫,供Servlet容器訪問。
Servlet容器在加載和初始化JavaWeb應用時會讀取它的web.xml文件,從中獲得Web應用的發布信息。
如下添加一個Servlet映射:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>MoviesServlet</servlet-name> <servlet-class>dao.MoviesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MoviesServlet</servlet-name> <url-pattern></url-pattern> </servlet-mapping> </web-app>
JavaWeb:Servlet技術