1. 程式人生 > >二、Servlet客戶端HTTP請求和服務端HTTP響應

二、Servlet客戶端HTTP請求和服務端HTTP響應

Servlet客戶端HTTP請求和服務端HTTP響應

關於HTTP知識的補充

  1. B/S程式結構
    JavaWeb是用於開發B/S模式的動態網頁技術,主要包含
    JSP、 Servlet等元件規範。
    B/S程式結構

  2. HTTP 訊息結構:

    • HTTP是基於客戶端/服務端(C/S)的架構模型,通過一個可靠的連結來交換資訊,是一個無狀態的請求/響應協議。

    • 一個HTTP”伺服器”同樣也是一個應用程式(通常是一個Web服務,如Apache Web伺服器或IIS伺服器等),通過接收客戶端的請求並向客戶端傳送HTTP響應資料。

  3. 客戶端請求訊息

客戶端傳送一個HTTP請求到伺服器的請求訊息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求資料四個部分組成,下圖給出了請求報文的一般格式:

  1. 伺服器響應訊息

HTTP響應也由四個部分組成,分別是:狀態行、訊息報頭、空行和響應正文。

  1. HTTP請求/響應格式:

HTTP請求格式

Request Header:
POST /serlvet-project1/demo1.html HTTP/1.1
Host: localhost:8088
Content-Length: 21
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;
q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Request Body:
name=scott&pwd=123456

HTTP響應格式

Response Header:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: W/"588-1473339581409"
Last-Modified: Thu, 08 Sep 2016 12:59:41 GMT
Content-Type: text/html
Content-Length: 588
Date: Thu, 08 Sep 2016 12:59:54 GMT
Response Body:
<html>
<head><title>示例1</title></head>
<body
>
<h1>這是一個HTML頁面</h1></body> </html>

Servlet客戶端HTTP請求

當瀏覽器請求網頁時,它會向 Web 伺服器傳送特定資訊,這些資訊不能被直接讀取,因為這些資訊是作為 HTTP 請求的頭的一部分進行傳輸的。

  1. 瀏覽器端的重要頭資訊
頭資訊 描述
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 這個頭資訊識別發出請求的瀏覽器或其他客戶端,並可以向不同型別的瀏覽器返回不同的內容。

2. 讀取 HTTP 頭的方法

方法 描述
Cookie[] getCookies() 返回一個數組,包含客戶端傳送該請求的所有的 Cookie 物件。
Enumeration getAttributeNames() 返回一個列舉,包含提供給該請求可用的屬性名稱。
Enumeration getHeaderNames() 返回一個列舉,包含在該請求中包含的所有的頭名。
Enumeration getParameterNames() 返回一個 String 物件的列舉,包含在該請求中包含的引數的名稱。
HttpSession getSession() 返回與該請求關聯的當前 session 會話,或者如果請求沒有 session 會話,則建立一個。
HttpSession getSession(boolean create) 返回與該請求關聯的當前 HttpSession,或者如果沒有當前會話,且建立是真的,則返回一個新的 session 會話。
Locale getLocale() 基於 Accept-Language 頭,返回客戶端接受內容的首選的區域設定。
Object getAttribute(String name) 以物件形式返回已命名屬性的值,如果沒有給定名稱的屬性存在,則返回 null。
ServletInputStream getInputStream() 使用 ServletInputStream,以二進位制資料形式檢索請求的主體。
String getAuthType() 返回用於保護 Servlet 的身份驗證方案的名稱,例如,”BASIC” 或 “SSL”,如果JSP沒有受到保護則返回 null。
String getCharacterEncoding() 返回請求主體中使用的字元編碼的名稱。
String getContentType() 返回請求主體的 MIME 型別,如果不知道型別則返回 null。
String getContextPath() 返回指示請求上下文的請求 URI 部分。
String getHeader(String name) 以字串形式返回指定的請求頭的值。
String getMethod() 返回請求的 HTTP 方法的名稱,例如,GET、POST 或 PUT。
String getParameter(String name) 以字串形式返回請求引數的值,或者如果引數不存在則返回 null。
String getPathInfo() 當請求發出時,返回與客戶端傳送的 URL 相關的任何額外的路徑資訊。
String getProtocol() 返回請求協議的名稱和版本。
String getQueryString() 返回包含在路徑後的請求 URL 中的查詢字串。
String getRemoteAddr() 返回傳送請求的客戶端的網際網路協議(IP)地址。
String getRemoteHost() 返回傳送請求的客戶端的完全限定名稱。
String getRemoteUser() 如果使用者已通過身份驗證,則返回發出請求的登入使用者,或者如果使用者未通過身份驗證,則返回 null。
String getRequestURI() 從協議名稱直到 HTTP 請求的第一行的查詢字串中,返回該請求的 URL 的一部分。
String getRequestedSessionId() 返回由客戶端指定的 session 會話 ID。
String getServletPath() 返回呼叫 JSP 的請求的 URL 的一部分。
String[] getParameterValues(String name) 返回一個字串物件的陣列,包含所有給定的請求引數的值,如果引數不存在則返回 null。
boolean isSecure() 返回一個布林值,指示請求是否使用安全通道,如 HTTPS。
int getContentLength() 以位元組為單位返回請求主體的長度,並提供輸入流,或者如果長度未知則返回 -1。
int getIntHeader(String name) 返回指定的請求頭的值為一個 int 值。
int getServerPort() 返回接收到這個請求的埠號。
int getParameterMap() 將引數封裝成 Map 型別。
  1. HTTP Header請求例項:

在Java Resources下建一個ServletTest類:

package cn.xdl.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 這是一個HTTP Header請求例項
 * 
 * 
 * 使用 HttpServletRequest 的 getHeaderNames() 方法讀取 HTTP 頭資訊。該方法返回一個列舉,包含與當前的 HTTP 請求相關的頭資訊。
 */
@WebServlet("/ServletTest")
//擴充套件HttpServlet類
public class ServletTest extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    //處理GET方法請求的方法
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //設定響應內容型別
        response.setContentType("text/html;charset=utf-8");
        //建立輸出流物件
        PrintWriter out = response.getWriter();
        String title = "HTTP Header請求例項";
        //建立HTML型別文件
        String docType = "<!DOCTYPE html> \n";
        out.println(docType +
        "<html>\n" +
        "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+
        "<body bgcolor=\"#f0f0f0\">\n" +
        "<h1 align=\"center\">" + title + "</h1>\n" +
        "<table width=\"100%\" border=\"1\" align=\"center\">\n" +
        "<tr bgcolor=\"#949494\">\n" +
        "<th>Header 名稱</th><th>Header 值</th>\n"+
        "</tr>\n");
        //建立表頭列舉物件
        Enumeration headerNames = request.getHeaderNames();

        //遍歷headerName物件
        while (headerNames.hasMoreElements()) {
            String paramName = (String) headerNames.nextElement();
            out.print("<tr><td>" + paramName + "</td>\n");
            String paramValue = request.getHeader(paramName);
            out.println("<td> " + paramValue + "</td></tr>\n");
            out.println("</table>\n</body></html>");
        }
    }
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    // 處理 POST 方法請求的方法
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
  • 對應的 web.xml 配置為:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>ServerTest</display-name>
      <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      <servlet>  
    <!-- Servlet類的別名 ,可以不與java類名相同 ,但<servlet>與<servlet-mapping>兩者中的<servlet-name>必須一致 -->  
    <servlet-name>TestOne</servlet-name>  
    <!-- 所在的包,為了避免出現錯誤,一定要寫全名 -->  
    <servlet-class>cn.xdl.servlet.ServletTest</servlet-class>  
      </servlet>  
      <servlet-mapping>  
    <servlet-name>TestOne</servlet-name>  
    <!-- 提供訪問的網址,供瀏覽器使用 -->  
    <url-pattern>/test</url-pattern>  
      </servlet-mapping>  
    </web-app>

Servlet 伺服器HTTP響應

響應通常包括一個狀態行、一些響應報頭、一個空行和文件。一個典型的響應如下所示:

    HTTP/1.1 200 OK
    Content-Type: text/html
    Header2: ...
    ...
    HeaderN: ...
      (Blank Line)
    <!doctype ...>
    <html>
    <head>...</head>
    <body>
    ...
    </body>
    </html>

狀態行包括 HTTP 版本(在本例中為 HTTP/1.1)、一個狀態碼(在本例中為 200)和一個對應於狀態碼的短訊息(在本例中為 OK)。

  • 從 Web 伺服器端返回到瀏覽器有用的 HTTP 1.1 響應報頭
頭資訊 描述
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 響應報頭的方法

方法 描述
String encodeRedirectURL(String url) 為 sendRedirect 方法中使用的指定的 URL 進行編碼,或者如果編碼不是必需的,則返回 URL 未改變。
String encodeURL(String url) 對包含 session 會話 ID 的指定 URL 進行編碼,或者如果編碼不是必需的,則返回 URL 未改變。
boolean containsHeader(String name) 返回一個布林值,指示是否已經設定已命名的響應報頭。
boolean isCommitted() 返回一個布林值,指示響應是否已經提交。
void addCookie(Cookie cookie) 把指定的 cookie 新增到響應。
void addDateHeader(String name, long date) 新增一個帶有給定的名稱和日期值的響應報頭。
void addHeader(String name, String value) 新增一個帶有給定的名稱和值的響應報頭。
void addIntHeader(String name, int value) 新增一個帶有給定的名稱和整數值的響應報頭。
void flushBuffer() 強制任何在緩衝區中的內容被寫入到客戶端。
void reset() 清除緩衝區中存在的任何資料,包括狀態碼和頭。
void resetBuffer() 清除響應中基礎緩衝區的內容,不清除狀態碼和頭。
void sendError(int sc) 使用指定的狀態碼傳送錯誤響應到客戶端,並清除緩衝區。
void sendError(int sc, String msg) 使用指定的狀態傳送錯誤響應到客戶端。
void sendRedirect(String location) 使用指定的重定向位置 URL 傳送臨時重定向響應到客戶端。
void setBufferSize(int size) 為響應主體設定首選的緩衝區大小。
void setCharacterEncoding(String charset) 設定被髮送到客戶端的響應的字元編碼(MIME 字符集)例如,UTF-8。
void setContentLength(int len) 設定在 HTTP Servlet 響應中的內容主體的長度,該方法設定 HTTP Content-Length 頭。
void setContentType(String type) 如果響應還未被提交,設定被髮送到客戶端的響應的內容型別。
void setDateHeader(String name, long date) 設定一個帶有給定的名稱和日期值的響應報頭。
void setHeader(String name, String value) 設定一個帶有給定的名稱和值的響應報頭。
void setIntHeader(String name, int value) 設定一個帶有給定的名稱和整數值的響應報頭。
void setLocale(Locale loc) 如果響應還未被提交,設定響應的區域。
void setStatus(int sc) 為該響應設定狀態碼。