JavaWeb之Servlet:請求 與 響應


1 引入

瀏覽器和服務器的種類都有很多,要在它們之間通訊,必定要遵循一定的准則,而http協議就是這樣的一個"准則"。

Http協議:規定了 瀏覽器 和 服務器 數據傳輸的一種格式。

當瀏覽器想要獲取服務器的服務,就會往服務器發送一個請求,這個請求就會使用Http協議規定的格式發送到服務器,而服務器收到這個請求后,也會按照Http協議規定的格式,把服務器的響應發給瀏覽器。

 

下面我們看一下這種"格式"的一個實例

請求的格式:

GET /day09/first HTTP/1.1             -- 請求行
Host: localhost:8080                  --請求頭(多個鍵值對)
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,zh-cn;q=0.8,zh;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
                                  --空行
name=eric&password=123456         --實體內容

 

響應的格式:

HTTP/1.1 200 OK                        --響應行
Server: Apache-Coyote/1.1                --響應頭(多個鍵值對)
Content-Type: text/html;charset=utf-8
Content-Length: 46
Date: Sat, 22 Nov 2014 01:42:06 GMT
                                    --空行
xxxxxx                                --實體內容(瀏覽器主體窗口看到的部分)

現在只要注意格式即可,具體內容我們下面一一講解

 

2.Http請求

    2.1請求行  

          GET /day09/first HTTP/1.1

  請求行中主要有三個部分  :

        1)GET                代表請求的方式。常用的有:GET請求,和 POST請求。

                    請求方式:GETPOSTHEADPUTCONNECTTRACE

 

        2)/day09/first      代表請求想要獲得的資源的URI

                   uri : 統一資源標記符。

                   url:統一資源定位父。

 

        3)HTTP/1.1    代表請求格式的http協議的版本。  

                    http:1.0 : 當前瀏覽器和服務器建立連接后,一次連接只能發出一次請求。

                    http:1.1: 當前瀏覽器和服務器建立連接后,一次連接可以發出多次請求。

那么GET和POST方式為什么事最常用的? 這就要關系到我們的表單。

html表單中只支持的請求的方式只有兩個值:GET 和 POST。

下面是表單的一段代碼:

  

<form action="提交的地址" method="GET/POST">
    用戶名:<input type="text" name="name"/>
    密碼:<input type="password" name="password"/>
    <input type="submit" value="提交"/>
</form>

表單提交后,表單數據就會隨請求一起發送到服務器,數據寫在了請求里面,但是GET方式 和 POST方式 把數據寫在了請求內的不同地方。

 

Get方式

GET /day09/testGetPost.html?name=eric&password=123456 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,zh-cn;q=0.8,zh;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/day09/testGetPost.html
Connection: keep-alive

可以看到,Get方式提交的請求,表單的數據會寫在請求行里,並且在請求資源后用 問號 分開。

所以,表單數據會隨着顯示在瀏覽器的地址欄,Get方式不適合提交敏感數據,並且數據量不能太大,不能超過1KB.

 

POST方式

POST /day09/testGetPost.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,zh-cn;q=0.8,zh;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/day09/testGetPost.html
Connection: keep-alive

name=eric&password=123456

1)參數放在請求的實體內容中。參數之間以&分割。

2POST方式可以提交敏感數據

3POST提交數據大小沒有限制。

 

以上就是 請求行 中的的分析,下面我們來分析請求頭。

2.2請求頭

Accept: text/html,image/*    -- 瀏覽器告訴服務器支持的數據類型
Accept-Charset: ISO-8859-1   -- 瀏覽器支持的編碼
Accept-Encoding: gzip,compress   ---瀏覽器支持的數據壓縮格式
Accept-Language: en-us,zh-      --瀏覽器支持的語言
Host: www.it315.org:80            --瀏覽器需要訪問的主機和端口
If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT  --瀏覽器最后更新的緩存時間
Referer: http://www.it315.org/index.jsp     --當前請求來自於哪個資源
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)  --瀏覽器類型
Cookie:name=eric                  --瀏覽器保存的cookie信息
Connection: close/Keep-Alive         --瀏覽器連接的狀態。close:關閉。keep-alive:保持連接
Date: Tue, 11 Jul 2000 18:23:51 GMT    --請求發出的時間

請求頭內包含了很多來自瀏覽器的信息,我們可以從請求頭得到這些信息,這些信息實際上是一些鍵值對,用這些信息來判斷瀏覽器用戶的狀態,並且利用這些信息來實現一些功能。

 

那么我們接收到這些封裝好的信息,如何利用代碼得到呢?

在java中有這樣的一個類,用於得到請求行里面的信息:      

HttpServletRequest對象:用於得到請求信息(十分重要),然后處理,得出不同的響應。

         核心方法:

            請求行:

              request.getMethod();  得到請求方式

              request.getRequestURI() / getRequestURL()   得到請求的資源的url

              request.getProtocol()   得到協議版本

            請求頭:

              request.getHeader(頭名稱)

              request.getHeaderNames();    得到所有的頭

              request.getHeaders(頭名稱)        得到同名頭的值

            實體內容:

              request.getInputStream();  得到實體內容的一個輸入流

 

那么如何得到這個對象呢?我們在服務器建一個 servlet ,然后重寫一下父類的doGet()方法,doGet方法就是瀏覽器以Get方式發送請求道服務器時,服務器就會執行doGet()方法里的內容,看下面一段代碼:

public class TestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
    }
}

我們可以看到,doGet()方法的參數中,就有那么一個HttpServletRequest類型的參數,也就是說,在doGet()方法中,我們可以利用這個參數來調用上面說的HttpServletRequest對象的核心方法,來取得請求里的數據!

下面我們利用這些方法獲取 請求行 里的信息:

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String method = request.getMethod();
        System.out.println("method is :" + method);
        String requestURI = request.getRequestURI();
        System.out.println("requestURI is :" + requestURI);
        String protocol = request.getProtocol();
        System.out.println("protocol is :" + protocol);
    }

輸出結果:

method is :GET
requestURI is :/MyFirstProject/TestServlet
protocol is :HTTP/1.1

這樣就能獲取請求行里的信息了!

同理!獲取請求頭內的鍵值對的信息,還有實體內容的信息,也可以利用doGet()方法內的HttpServletRequest來完成,此處不一一演示。那么我們下面研究下doGet()方法!

 

doxxx()方法

上面說過以GET方式提交的請求,Servlet就會調用doGet()方法來處理,十分容易理解的~

所以,如果瀏覽器以POST方式來提交請求,Servlet就會調用它的doPost()方法來處理了~

對應的,請求方式有這么多種:GET、POST、HEAD、PUT、CONNECT、TRACE

以哪種方式提交的請求,Servlet就會調用doxxx()方法來處理對應的請求了~

 

獲取表單的數據

表單的數據會存儲在請求中:

     請求行(get方式)

              GET /day09/testGetPost.html?name=eric&password=123456 HTTP/1.1

      實體內容(post方式)

              name=eric&password=123456

細心的讀者可能會發現,上面介紹HttpServletRequest的核心方法中,雖然可以獲取請求中的數據,但是要清楚得區分出表單內容還是很麻煩,比如說我們想要獲得name的值,那么就要寫一個程序去判解析字符串,得到name的值。這顯得十分麻煩,所以,Servlet中提供了一些簡便的方法讓我們獲取表單數據。

  

    統一的獲取請求中表單參數的方法:

      request.getParameter(參數名)         獲取單個值的參數,比如獲得name的值,就這樣寫:request.getParameter("name");

      request.getParameterValues(參數名)  獲取多個值的參數,有些表單一個屬性有多個值,例如你有多個愛好,那么久調用這個方法獲取愛好的多個值。

      request.getParameterNames();         獲取所有的參數,這個方法獲得表單的所有參數的名字,例如一個表單中有:name,id,hobit,address,phone等。

 

現實生活中,根據不同的需要,用戶提交的表單可能是用Get方式提交的,也可能用POST方式提交的,表單數據根據不同的提交方式存儲在請求的不同地方,但是我們得到表單數據后要對數據的處理是一樣的,如果在doPost()和doGet()中都寫同一個處理方法就顯得代碼太繁瑣了,那么我們如何處理這種情況?

  我們可以在doPost()方法中調用doGet()方法,在doGet()判斷請求的方式,然后根據兩種請求得到數據,然后就對這些數據進行處理。

 

 請求參數的編碼問題

1POST方式

 

request.setCharacterEncoding(碼表);   

 

 

用於設置獲取實體內容參數時查詢的碼表。建議放在第一 行代碼

2Get方法

2.1 手動解碼:(推薦使用)

if("GET".equals(request.getMethod())){

ah = new String(ah.getBytes("iso-8859-1"),"utf-8");

}

2.2 修改服務器的配置文件(依賴服務器,不推薦使用)

找到%tomcat%/conf/server.xml,修改以下配置

<Connector port="8080" protocol="HTTP/1.1" 

               connectionTimeout="20000" 

               redirectPort="8443" URIEncoding="utf-8"/>  加入URIEncoding屬性,設置URI后面參數的編碼

 

 

HTTP相應

說完了請求,我們說一下相應,如果你懂了請求里的內容,響應內容就絕對沒問題了!

響應瀏覽器想服務器發出請求,服務器作出響應,我們看以下響應的格式:

HTTP/1.1 200 OK                        --響應行
Server: Apache-Coyote/1.1                --響應頭(多個鍵值對)
Content-Type: text/html;charset=utf-8
Content-Length: 46
Date: Sat, 22 Nov 2014 01:42:06 GMT
                                    --空行
xxxxxx  

響應的格式和請求的格式相似。

 

響應行

由三部分組成:

    Http協議版本      HTTP/1.1 

 

    狀態碼: 服務器告訴瀏覽器,請求處理的結果。

    常用的狀態:

          200     請求處理完成

          302     客戶端需要進一步發送請求才能完成過程。通常該狀態碼與location響應頭一起使用。

          404     請求的資源沒有找到

          500     服務器的資源出錯。

     狀態描述: 對狀態碼的補充

 

響應頭

Location: http://www.it315.org/index.jsp   ---重定向的地址。通常和302狀態碼一起使用。
Server:apache tomcat                   --服務器的類型
Content-Encoding: gzip                   -- 服務器發送給瀏覽器的內容壓縮格式 
Content-Length: 80                     --服務器發送瀏覽器的數據長度
Content-Language: zh-cn                   --服務器發送給瀏覽器的內容語言
Content-Type: text/html; charset=GB2312    --服務器發送給瀏覽器的內容類型和編碼
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT   --服務器資源的最后修改時間
Refresh: 1;url=http://www.it315.org      --定時刷新或者隔n秒跳轉頁面
Content-Disposition: attachment; filename=aaa.zip  -- 告訴瀏覽器以下載方式打開資源
Transfer-Encoding: chunked 
Set-Cookie:SS=Q0=5Lb_nQ; path=/search      --服務器發送瀏覽器的cookie信息
Expires: -1                               --通知瀏覽器不使用緩存
Cache-Control: no-cache                    --通知瀏覽器不使用緩存
Pragma: no-cache                         --通知瀏覽器不使用緩存
Connection: close/Keep-Alive                連接狀態
Date: Tue, 11 Jul 2000 18:23:51 GMT          響應的發出時間

 

 最后就是實體內容。  我們可以使用HttpServletResponse對象來操作這些內容,然后發送給瀏覽器,具體做法其實和HttpServletRequest對象類似。在此不一一講解。


免責聲明!

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



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