Servlet請求和響應


在Java Web中Servlet、請求和響應是最基本的三個對象,在Web容器的管理下,這三者能夠完成基本的HTTP請求處理。

Servlet的作用是為客戶提供服務。servlet的角色是接受一個客戶的請求,再返回一個響應。請求可能非常簡單,例如:給我提供一個歡迎頁面;也可能非常復雜,例如:為當前的購物車結賬,這個請求會帶一些客戶端傳來的參數,servlet需要知道自己如何使用請求中的參數,還需要知道該返回什么樣的響應。

一、Servlet

1. Servlet受容器管理

Java Web服務器處理用戶請求的基本過程:用戶在客戶端點擊一個鏈接,瀏覽器會向Web應用服務器發送一個URL請求,該URL會指向一個servlet;Web容器看出這個請求指向某個servlet A,就會創建兩個對象(HttpServletRequest和HttpServletResponse),並分配或創建一個線程,調用servlet A對應的service方法(上述請求和響應對象作為參數);service根據HTTP請求區分出客戶端發來的是GET還是POST請求,並調用對應的doGet()或doPost()方法;在doGet()或doPost()方法中進行業務邏輯的處理,處理完成后的結果通過響應對象返回寫回給客戶端。

2. Servlet的生命周期

在容器啟動時,XXXServlet在JVM的管理下被實例化為一個對象,這時候它還不是servlet,需要在容器的管理下調用init()方法進行初始化,獲得ServletConfig和ServletContext對象的引用后,才稱為一個真正的Servlet。

1)init()

  • 何時調用?servlet實例創建后,並在servlet能為客戶請求提供服務之前,容器需要通過init方法初始化servlet。

  • 作用?初始化servlet實例,使之獲得web容器的相關信息

  • 是否會被覆蓋?有可能

2)service()

  • 何時調用?當一個客戶請求到來時,容器會創建(或從線程池分配一個線程),並調用servlet的service方法

  • 作用?這個方法會確定HTTP方法(GET or POST),並調用對應的servlet方法——doGet或doPost;

  • 是否會被覆蓋?可以,但是不會

3)doGet()或doPost()

  • 何時調用?

  • 作用?具體的業務邏輯

  • 是否會被覆蓋?至少要覆蓋其中之一

關鍵點:每個請求都在一個單獨的線程中運行!

3. Servlet的繼承體系

  • servlet接口:javax.servlet.Servlet,表示所有的Servlet都有這5個方法,其中init、service和destroy三個方法和servlet的生命周期有關;

  • GenericServlet:javax.servlet.GenericServlet,這是一個抽象類,它實現了開發者需要的大部分基本servlet方法,大多數servlet的“servlet行為”都來自這個類;

  • HttpServlet:javax.servlet.http.HttpServlet,這也是一個抽象類,它實現了自己的service()方法,處理servlet的HTTP特性(service方法不僅僅只處理HTTP請求)。

  • MyTestServlet:這是開發者自己編寫的處理類,一般只需要實現doGet()和doPost()方法。

二、請求和響應

1. ServletRequest的繼承體系

HttpServletRequest的API與HTTP有關,例如:Cookie、首部(Header)和會話(Session)等;

2. ServletResponse的繼承體系

ServletResponse(響應)也是類似,用於幫助servlet給客戶端返回處理結果,而HttpServletResponse增加了HTTP相關的內容(例如:錯誤、cookie和首部)等API。

HttpServletRequest和HttpServletResponse這些都是servlet規范里指定的接口,而web容器開發商(例如tomcat)會負責實現這些接口,例如:HttpServletResponseWrapper和ApplicationHttpResponse等,作為開發者,我們只需要知道,在處理doGet()和doPost方法時,容器會給這個方法傳HttpServletRequest和HttpServletResponse兩個參數。

3. GET和POST的區別

  • POST方法有請求體

  • GET方法的查詢參數直接跟在URL后面,不夠安全;

  • GET請求可以建立書簽,POST請求則不能

  • GET請求是冪等的,POST請求不是(GET請求僅僅用於查詢一些數據,POST請求則用於在服務器上更新數據),在業務上會遇到既需要POST請求,又需要保證請求冪等的情況(例如庫存扣減),這種情況需要我們出具對應的實現方案。參見:

4. HTTP請求的API

  • getHeader(),可以獲取首部信息,例如request.getHeader("User-Agent")可以獲取客戶端的平台和瀏覽器信息。

  • getIntHeader(),如果首部信息中的“key/value”對中的value是int類型的,可以使用這個方法直接獲取值而不需要顯式類型轉換

  • getCookies(),可以獲取與請求相關的cookie

  • getSession(),可以獲取與請求相關的會話

  • getMethod(),可以獲取http方法

  • getInputStream(),可以獲取請求的輸入流

  • 求,可以獲取查詢字符串中的數據、對於POST請求,可以獲取請求體中的數據

  • getRemotePort(),獲取客戶端的端口號

  • getServerPort(),獲取服務端接受請求的端口號(請求一開始發送服務端的哪個端口?)

  • getLocalPort(),獲取服務端處理請求的端口號(請求最后是發送到服務端的哪個端口?)

5. HTTP響應的API

大多數情況下,使用響應只是為了向客戶發回數據。會對響應調用兩個方法:setContentType()和getWriter()。在此之后,可以將HTML或其他內容寫入到流。不過,你也可以使用響應設置首部、發送錯誤或增加Cookie。

  • setContentType(),設置響應返回的MIME類型

  • getOutputStream(),獲取HTTP輸出字節流

  • getWriter(),獲取HTTP輸出字符流

  • addCookie(Cookie cookie),給響應首部中增加cookie對象,注意這里不是增加“key/value”對

  • addHeader(),在響應首部中添加一個“key/value”對

  • setHeader(),在響應首部中設置一個“key/value”對;和addHeader()的區別是,如果響應首部中已經有對應的key存在,setHeader()會覆蓋現有的值,而addHeder()會新增一個“key/value”對,使用時需要注意

  • encodeRedirectURL(),對包含session ID的URL進行編碼。使用場景:在瀏覽器不支持使用cookie跟蹤會話時,可以使用URL重寫(即將URL重定向到另一個URL,而這個URL的后面會帶上session id傳給客戶端,這個URL在返回給客戶端之前需要經過編碼)

6. 重定向和請求派發

  • 重定向是讓瀏覽器訪問新的URL完成工作,用戶會在瀏覽器地址欄看到新的URL;

  • 請求派發是服務端的工作,是當前servlet委托另外的servlet完成請求,並給客戶端發回響應,用戶的瀏覽器地址欄的URL沒有改變;

原文鏈接:https://mp.weixin.qq.com/s/TTE364IxyqI4Gl9kVEVFXw


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM