跳到內容

Sun 認證 Web 元件開發人員/第 1 部分/HTTP 請求

來自華夏公益教科書,開放的書籍,開放的世界

HTTP 請求

[編輯 | 編輯原始碼]

HttpServletRequest 可能是整個 JEE 框架中最重要的介面。它是使用者與伺服器通訊的方式。每次使用者需要從伺服器獲取東西時,他都會發送一個請求,該請求在 Web 容器內被轉換為 HttpServletRequest 物件。

首先要注意的是 HttpServletRequest 擴充套件了另一個介面,即 ServletRequest 介面。這是因為 Web 容器並非設計為僅處理 HTTP 請求和響應,而是處理各種請求,使用多種協議。儘管如此,如前所述,HTTP 是最常用的協議,並且您可能在 100% 的時間內只會看到 HTTPRequests 輸入和 HTTPResponses 輸出。這就是 JEE API 有一個名為 javax.servlet.http 的特定包的原因,其中包含針對 HTTP 協議的所有特定類和介面。

HttpServletRequest 中有許多方法非常方便用於操作使用者的請求。您可以從 Web 容器為您建立的物件中獲取各種資訊。一些示例包括

  • HTTP 頭部
  • Cookie
  • 查詢字串
  • 使用者的 IP 和埠
  • 表單引數
  • 等等。

HttpServletRequest 物件最常見的用途是獲取使用者在 HTML 表單中傳送的引數。引數是伺服器從客戶端接收的用於特定任務的字串,例如:處理查詢或儲存或更新資料庫記錄。

引數透過兩種方式傳送:在 HTML 表單中和在查詢字串中。在這兩種方式中,引數都是由鍵標識的值。同一個鍵可以有多個值,這意味著同一個引數可以傳送兩次,具有兩個不同的值。一些有效的引數示例是

  • name=John
  • fname=John&lname=Doe&email=jdoe@gmail.com
  • query=java&lang=en
  • name=John&name=Mary&name=Josh

使用 POST 方法透過 HTML 表單傳送時,資料會發送在請求主體中,並且可以是任何大小。使用 GET 時,資料受 URL 最大大小的限制,這取決於瀏覽器或伺服器,因此不建議使用 GET 傳送大量資料。

下面您可以看到關於 HTML 表單和查詢字串的更詳細的解釋。

HTML 表單

[編輯 | 編輯原始碼]

HTML 表單是使用者向伺服器傳送資料的幾種方式之一。如前所述,HTML 表單可以透過兩種不同的方式傳送資料:POST 和 GET。如果要傳送更新伺服器內容的資料,建議使用 POST,有時因為資料量可能很大,有時因為可能存在不會在 URL 中加密的機密資料。

要使用 HTML 表單向伺服器傳送引數,只需命名並使用您想要的名稱識別表單子元素,然後在伺服器中按名稱獲取它。一個非常簡單的例子是使用者傳送以下表單

<form method="POST" action="someUrl.do">
    What is your name?<br />
    <input type="text" id="name" name="name" /><input type="submit" />
</form>

這將呈現類似於這樣的內容

Simple HTML form

然後,servlet 可以接收帶有引數的 HttpServletRequest 並列印一個hello訊息

package org.wikibooks.scwcd;

import java.io.IOException;
import java.io.PrintWriter;

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

public class MyServlet extends HttpServlet {

    public void doPost (HttpServletRequest request, 
            HttpServletResponse response) throws IOException, ServletException {
        
        String name = request.getParameter("name");
        if (name != null) {
            PrintWriter out = response.getWriter();
            out.println("Hello " + name + "!");
            out.flush();
        }
    }
}

這將導致一個頁面顯示訊息“Hello [使用者名稱]!”。

要檢視伺服器收到的所有引數,可以使用以下 Servlet

package org.wikibooks.scwcd;

import java.io.IOException;
import java.io.PrintWriter;

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

public class EchoParameters extends HttpServlet {

    public void doPost (HttpServletRequest request, 
            HttpServletResponse response) throws IOException, ServletException {
                PrintWriter out = response.getWriter();
		out.println("<html><body>All parameters:<ul>");
		Enumeration params = request.getParameterNames();
		String name;
		while (params.hasMoreElements()) {
			name = (String)params.nextElement();
			out.println("<li>Key : " + name + "<br />Values: <ul>");
			for (String value : request.getParameterValues(name)) {
				out.println("<li>" + value + "</li>");
			}
			out.println("</ul>");
		}
		
		out.println("</ul></body></html>");
		out.flush();
    }
}

查詢字串

[編輯 | 編輯原始碼]

查詢字串是一個格式特定的字串,附加在 URL 的末尾。該字串可以在問號符號 (?) 後附加,包含由與符號 (&) 分隔的鍵/值對。一個簡單的例子是 http://www.google.com/search?q=java,其中查詢字串是 q=java。這樣,伺服器會收到一個值為“java”的引數“q”,這意味著該 URL 是 google.com 域 (伺服器) 內的 search 資源的query。

要將值傳送到查詢字串中,只需在 HTML 表單中使用 GET 方法,如上所述。

瀏覽器會自動對 URL 進行編碼,以便伺服器能夠正確地解釋它,因為有一些特殊的符號不能直接傳送,例如 @。其中一些符號用於特殊目的,不得在查詢字串中的鍵或值中使用,因此必須對其進行編碼,否則伺服器將誤解 URL,查詢字串可能會損壞。[2] [3]。

查詢字串對於儲存應用程式狀態很有用:使用者所在的位置或他們執行的某些操作,可以將其新增書籤以供以後訪問。但要記住的是,由於它們可以儲存,因此查詢字串中不應包含機密資料,例如信用卡號碼。

HTTP 頭部

[編輯 | 編輯原始碼]

HTTP 頭部是客戶端(大多數情況下是瀏覽器)和伺服器用於檢查彼此想要什麼以及他們期望如何接收答案的協議特定命令。訪問標頭的最簡單方法是使用 HttpServletRequest.getHeader(String) 方法。它將返回一個表示伺服器為特定頭部接收到的標頭的值的 String

以下示例顯示了 servlet 如何將從客戶端接收的所有標頭以 HTML 格式傳送回去

package org.wikibooks.scwcd;

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

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

public class HttpHeadersExample extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		Enumeration names = request.getHeaderNames();
		String value = null, name = null;
		
		PrintWriter out = response.getWriter();
		
		out.println("<html><body>");
		out.println("<p>All HTTP Headers:<ul>");
		
		while (names.hasMoreElements()) {
			name = (String) names.nextElement();
			value = request.getHeader(name);
			out.println("<li><strong>" + name + "</strong>: " + value + "</li>");
		}
		out.println("</ul></p></body></html>");
		out.flush();
	}
}

這將導致以下 HTML 程式碼,用於特定瀏覽器

<html><body>
<p>All HTTP Headers:<ul>
<li><strong>host</strong>: localhost:8080</li>
<li><strong>user-agent</strong>: Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3</li>
<li><strong>accept</strong>: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</li>
<li><strong>accept-language</strong>: en-us</li>
<li><strong>accept-encoding</strong>: gzip,deflate</li>
<li><strong>accept-charset</strong>: ISO-8859-1,utf-8;q=0.7,*;q=0.7</li>
<li><strong>keep-alive</strong>: 300</li>
<li><strong>connection</strong>: keep-alive</li>
</ul></p></body></html>

參考文獻

[編輯 | 編輯原始碼]

[1] - Java 企業版 API - 應用程式程式設計介面

[2] - URL 編碼

[3] - HTML URL - 編碼參考

[4]

華夏公益教科書