今天是劉小愛學習JAVA的第89天。
感謝你的觀看,謝謝你。
話不多說,開始今天的學習:
在學習之前,先思考如下問題:
- 對于瀏覽器來說:
- 如何將用戶數據發送到服務器呢?
- 數據傳輸的格式是怎么樣的呢?
- 對于服務器來說:
- 如何獲取用戶提交的數據呢?
- 如何將結果響應給瀏覽器?
畫一張圖,對其做一個分析:
如果把servlet比作瀏覽器和服務器之間的一個通道,那么request和response也就是通道里的內容。
當然這樣說明肯定不太準確,但是初學這樣更好理解,今天就學一學這個request。
一、get、post請求
在學form表單的時候就知道了請求有get和post之分,當然請求方式不只有這兩個,但目前主要接觸這兩種。
分析下瀏覽器發送請求到服務器的流程:
①登錄頁面
這是我在網上找的一個bootstrap登錄頁面,其本質也就是一個form表單,只不過加入了美化。
form表單標簽有兩個屬性:
- action:也就是表單提交后會跳轉的路徑,我這邊設置的為“/getServlet”
- method:也就是請求方式,我這邊設置的是get請求。
詳情見下圖,模擬post請求時也就可以修改這兩個屬性。
②瀏覽器地址
當點擊登錄提交按鈕后,瀏覽器就會跳轉action中對應的那個路徑。其中get請求:會將參數拼接到url后面。
如何拼接的呢?
input標簽中的name屬性對應的值等于輸入框中輸入的值。
也就是:username=劉小愛。
③注解Servlet開發
使用注解開發的方式創建一個類GetServlet,其路徑為“/getServlet”。
而在①中點擊登錄時會跳轉“/getServlet”,所以會找到這個類,從而執行doGet()請求方法。
瀏覽器抓包觀察請求報文
這邊我又將①中表單請求方式改成post了,主要也是為了將get和post做一個總結對比。
一般是用谷歌瀏覽器,按F12進入開發調試,在Network選項中可以抓包。
①請求行
在get請求中參數是被拼接在url后面的。
而在post請求中是不拼接參數的。
正是因為如此,get請求不可以傳輸數據類較大的或者非文本數據,因為太長了url寫不下了哈哈哈。
②請求頭
以鍵值對的形式將信息傳輸給服務器。
③請求體
post請求的參數在請求體中,而get請求請求體為空。
二、request請求API
回到最先開始的幾個問題,瀏覽器將數據傳輸給服務器了。
那么服務器如何獲取這些數據呢?又如何進行處理呢?
在Java中一切都是對象,肯定有對應的類和對象。
1Request請求行
①getMethod()方法
其獲取的就是瀏覽器發起的請求方式,例子中是post請求。
②getRequestURI()方法
其獲取的就是瀏覽器訪問的路徑。
③getRemoteAddr()方法
這個是ip值,因為我的是本地電腦,所有就這樣了。
④getProtocol()方法
獲取的協議版本號,這里是HTTP/1.1。
2Request請求頭
請求頭中的信息是以鍵值對的形式傳送給服務器的。
其中關于getHeader()方法中的參數:user-agent。
- user:瀏覽器攜帶的用戶操作系統。
- agent:瀏覽器版本等信息。
老實說,這里面的信息就只能看懂一點點。
電腦系統為Win10,64位系統,后面還有能看出是用的谷歌瀏覽器訪問,其它的很多信息暫時不懂。
3Request請求體
①getParameter()方法
parameter,參數的意思。get請求的請求體為空,post請求參數需要從請求體中獲取。
參數名為鍵值對中的鍵,參數值為鍵值對中的值。
這個是一對一的獲取方式。
②getParameterValues()方法
上述的是一個參數名對應一個值,這個是對應多個值,比如復選框就可以選取多個值。
因為我用的是登錄頁面,只有用戶名和密碼。
但對該方法也要有一定的了解,該方法獲取的值是一個數組,使用Arrays類可以將其轉化成字符串再打印。
③getParameterMap()方法
看到Map第一反應就是鍵值對了,Map集合的兩種遍歷方式選擇一種遍歷打印即可。
三、request域對象和轉發
1request域對象
如何理解域對象呢?
前面也說了,servlet相當于管道,request相當于管道里的內容。
而內容自然是需要裝在容器里面的,這里的容器也就是request域對象。
和Java里的Map集合有一定的類似之處,就連API也很類似。
①setAttribute()
設定值,其中以鍵值對的形式存儲數據。
②getAttribute()
獲取值,根據key值獲取對應的value值。
③removeAttribute()
移除值,刪除對應的鍵值對。
以上就是幾個常用的API,和Java中的集合很相似。
2request轉發
什么叫轉發呢?
通俗地理解就是:根據瀏覽器的路徑,對應的servlet要處理請求,但是這個servlet不想處理,就可以轉發給另一個servlet來處理。
像極了我小時候遇到不喜歡吃的菜了,就給我爸媽吃的樣子……
舉一個例子來說明:
根據瀏覽器中的路徑,本來ForwardServlet要處理請求,但是它將請求轉發給OtherServlet了,最后就由OtherServlet來處理。
那如何使用轉發?其對應API為:
- getRequestDispatcher("/otherServlet"),參數即為需要轉發到的路徑。
- forward(),參數也就是請求和響應。
轉發小結:
- 例子中的轉發是轉發到了另一個Servlet,其實也可以轉發到一個固定靜態頁面。
- 無論轉發多少次,瀏覽器請求路徑沒有變化,對瀏覽器來說就只有一次請求。
- 所以轉發屬于服務器內部的跳轉行為,與瀏覽器無關。
- 轉發過程中數據是共享的,也就是存儲在域對象中的數據。
最后
謝謝你的觀看。
如果可以的話,麻煩幫忙點個贊,謝謝你。