J2EE HTTP的請求和響應原理,servlet處理原理

來源:互聯網
上載者:User

HTTP的請求與響應

    當發生下列事件時,瀏覽器都會向Web伺服器發送HTTP請求:

    1.使用者在網頁上點擊一個超連結;

    2.使用者提交在網頁上填好的表單;

    3.使用者在瀏覽器地址欄中輸入URL地址並斷行符號。

    Servlet中對HTTP請求的處理過程:

    1.Web瀏覽器通過開啟一個到Web伺服器的TCP Socket通訊端初始化一個HTTP請求,Socket的輸入資料流包含了HTTP請求資料,Socket的輸出資料流中包含了HTTP響應數。

    2.對於一個Servlet的每次訪問請求,Web容器都會解析Socket輸入資料流中的HTTP請求資料,建立一個請求對象,同時也建立一個響應對象。

    3.Web容器調用所請求的Servlet對象的service()方法,並將請求和響應對象作為參數傳遞給該方法,其中作為參數傳遞進來的響應對象就是HttpServletResponse對象,在Servlet對象的service()方法內部可以調用HttpServletRespnse對象的各種方法來建立響應訊息。

    4.HttpServletResponse響應對象給Servlet提供一個PrintWriter對象,使Servlet可以產生響應訊息體。

 

    使用者在提交網頁或表單時,瀏覽器向伺服器發送的要求方法有以下幾種:GET,HEAD,POST,PUT,DELETE,OPTION,REACE,在Servlet中每一種方法都對象一個要求方法,在使用時,我們一般只需在Servlet中實現需要的方法即可。要求方法最常用的是GET和POST方法,在以下這些條件下使用這兩種方法:1.請求一個靜態頁面或圖形檔案時使用GET方法,因為僅需要傳送檔案名;2.發送大資料時,使用POST方法;3.上傳檔案時,使用POST方法;4.發送使用者名稱、密碼或其它保密資訊時使用POST方法。

    在Servlet中我們需要訪問請求行的資訊,需要用請求對象調用以下的方法:

    getMethod():擷取HTTP的要求方法,如:GET和POST等

   getRequestURI():擷取請求的URI資源,如:/lovobook/index.html

    getRequestURL():擷取請求的URL,包含協議名、伺服器名或IP、連接埠號碼和請求資源但不包括查詢字串參數,如:http://127.0.0.1:8080/lovobook/index.html

    getQueryString():擷取請求URL後面的查詢字串,如:name=aaa(POST沒有這個方法)

    getProtocol():擷取協議名和版本號碼,如:HTTP/1.1

    getContextPath():擷取請求URI資源的上下文路徑,始終以"/"開頭,如:/lovobook

    getServletPath():擷取Servlet的映射路徑(參見http://hi.baidu.com/pangang107/blog/item/fd664d2d0cad45f48b139925.html中Servlet在web.xml中的部署)

    HTTP要求標頭通過HttpServletRequest對象的下列方法調用:

    getHeader(String name):返回要求標頭的值,如沒有則返回null

    getHeaders(String name):如果請求的值有多個,用此方法返回一個Enumeration枚舉包含這些值

    getHeaderNames():返回一個Enumeration包含所有的要求標頭的名稱

    getIntHeader(String name):擷取要求標頭的值,並轉換為int類型,不存在則返回1,不能轉換則跑異常,NumberFormatException

    getDateHeader(String name):擷取特定要求標頭的值,並轉換為Date類型

    通過請求對象HttpServletRequest調用以下方法獲得請求參數,即表單資料:

    getParameter(String parameterName):通過參數名(區分大小寫,與表單參數名相同)獲得表單參數值,對GET/POST方法都適用,如果沒有這個參數,則返回null

    getParameterValues(String parameterName):返回一個數組包含,這個參數名的所有值

    getParameterNames():返回一個Enumeration包含所有的參數名

    注意,如果上傳檔案時網頁上表單應包含這些參數:

    <form type="file" method="post" enctype="mutipart/form-data">

    ....

    </form>

   請求轉寄可以通過javax.servlet.RequestDispatcher對象來實現,RequestDispatcher對象可以通過下列方式得到:

   getRequestDispatcher(String path):path路徑必須以根目錄"/"開始,並且可以導向Web應用程式中的任何資源,如:request.getRequestDispatcher("/HelloWorld"),容器會把這看作是從Web應用程式的根開始,如果不用"/"開始,容器會認為路徑相對於原來的請求。

    getNamedDispatcher(String name):name名稱必須在web.xml中servlet-name元素中定義的名稱

    通過內容物件ServletContext的getRequestDispatcher()得到,路徑必須以根目錄"/"開始

    RequestDispatcher對象提供了兩種方法來包含不同的資源,以及將請求轉寄到不同資源

    forward(ServletRequest, ServerletResponse):派發請求和響應對象到RequestDispatcher對象所確定的新資源(Servlet,JSP,或HTML等),該資源通過利用請求和響應對象來處理HTTP請求,用法如:request.getRequestDispatcher("/success.html").forward(request,response);

    include(ServletRequest, ServletResponse):用法同forward()方法,有一些限制,它能包含伺服器端的資源,被包含的資源不能改變響應狀態碼或設定頭資訊,任何制式改變的嘗試都會被忽略,一般情況下不用。

 

    響應狀態代碼的設定一般使用response.setStaauts(int)方法,但HttpServletResponse定義了兩種情況的專用方法:

    sendError(int code,String message):產生一個404應答,同時產生一個簡短的html錯誤資訊文檔發送給用戶端

    sendRedirect(String URL):產生一個302應答,同時在Location中指示新文檔的URL地址,也就是重新導向

    設定回應標頭資訊的方法:

    containsHeader(String name):返回一個布爾值指示是否設定了指定的回應標頭

    setHeader(String name,String value):用一個給定的名稱和字串值設定回應標頭的通用方式,如過回應標頭已本設定,則會覆蓋

    setIntHeader(String name,int value):同上,值為int類型

    setDateHeader(String name,long date):同上,date為日期值,日期值應該反應自1970-1-1日(GMT)以來的精確到毫秒的長整數

    addHeader(String name,String value):用於在response中添加一個給定名稱和字串的回應標頭,而不管是否已經存在同名的前序,因為該方法允許回應標頭有多個值

    addIntHeader(String name,int value):同上,值為int類型

    addDateHeader(String name,long date):同上,值為日期值的長整型數值

    setContentType(String mimetype):設定返回給用戶端的MIME類型,大多數的Servlet都要用這個方法,用法如:responde.setContentType("text/html;charset=utf-8");

    addCookie(Cookie c):用於向Set-Cookie前序插入一Cookie,因為可以設定多個Cookie,所有沒有setCookie方法。

    重新導向的流程為:1.Web瀏覽器通過HTTP發送請求;2.伺服器端響應的Servlet把真實串連URL地址和302響應碼發送到用戶端;3.響應結束,瀏覽器斷開但前串連,然後在根據Location回應標頭的URL地址,重新發出HTTP請求。設定重新導向:

    一般情況下使用絕對位址,並且是完整的URL路徑來實現重新導向,如:

   response.sendRedirect("http://127.0.0.1:8080/lovobook/bar.html");

    或者從Web應用程式的跟"/"開始,使用一個URL路徑,如:

    response.sendRedirect("/lovobook/bar.html");

    Web應用程式可以部署到War檔案中執行,HttpServletRequest的getContextPath()方法得到Web應用程式根目錄的絕對路徑,可以用於一個據對URL地址的聯合,如:

    response.sendRedirect(request.getContextPath() + "/lovobook/bar.html");

    設定自動重新整理和等待頁(不能保證所有的瀏覽器都支援),代碼:

    response.setHeader("Refresh","time;URL=url");

    如:response.setHeader("Refresh","10;URL=http://127.0.0.1/foo.html");

    得到請求中參數的原始位元組資料,可以使用HttpServletRequest對象的getInputStream()方法得到位元組流,或通過getReader()方法來得到字元流,通過這些來訪問表單資料。

    得到請求之後伺服器用字元流java.io.PrintWriter對象(通過response.getWriter()來得到)用來返迴文本內容,位元組流ServletOutputStream對象(通過response.getOutputStream()來得到)允許開發人員用來操作位元組流

 

1、  HttpServletRequest簡介:

(1)WEB用戶端發送給WEB伺服器的HTTP請求訊息分為三個部分:

a)         請求行 POST /demo/login HTTP/1.1

b)        請求訊息頭

c)        訊息本文(也叫實體內容) username=xxxx&password=1234

(2)Servlet API中定義的ServletRequest介面類用於封裝請求訊息。

(3)HttpServletRequest是專用於HTTP協議的ServletRequest子介面,它用於封裝HTTP請求訊息。

(4)在service()方法內部調用HttpServletRequest對象的各種方法來擷取請求訊息。

2、擷取請求行的相關資訊

(1)HTTP請求訊息的請求行包括請求方式、資源路徑和HTTP協議版本:

       GET /it315/servlet/RequestURI?param1=a&param2=b HTTP/1.1

(2)getMethod方法返回HTTP請求訊息中的請求方式。

(3)getRequestURI方法返回請求行中的資源名部分。

(4)getQueryString 方法返回請求行中的參數部分。

(5)getProtocol方法返回請求行中的協議名和版本。

(6)getContextPath方法返回請求資源所屬於的WEB應用程式的路徑。

(7)getPathInfo方法返回請求URL中的額外路徑資訊。額外路徑資訊是請求URL中的位於Servlet的路徑之後和查詢參數之前的內容,它以“/”開頭。

(8)getPathTranslated方法返回URL中的額外路徑資訊所對應的資源的真實路徑。

(9)getServletPath方法返回Servlet的名稱或Servlet所映射的路徑。 

3、擷取請求行的相關資訊---------舉例

 

4、擷取網路連接資訊

(1)getRemoteAddr方法返回傳出請求的客戶機的IP地址,其格式為“192.168.0.3”這種形式的字元文本。 (*)

(2)getRemoteHost方法返回傳出請求的客戶機的完整主機名稱,即“pc1.it315.org”這種格式。

(3)getRemotePort方法返回傳出請求的客戶機所使用的網路介面的連接埠號碼。

(4)getLocalAddr方法返回WEB伺服器上接收當前請求的網路介面的IP地址。

(5)getLocalName方法返回WEB伺服器上接收當前請求的網路介面的IP地址所對應的主機名稱。

(6)getLocalPort方法返回WEB伺服器上接收當前請求的網路介面的連接埠號碼。

(7)getServerName方法返回當前請求所指向的主機名稱。

(8)getServerPort方法返回當前請求所已連線的服務器連接埠號碼。

(9)getScheme方法返回請求的協議名,例如http、https或ftp。

(10)getRequestURL方法返回用戶端發出請求時的完整URL。   

5、擷取所有要求標頭的編程執行個體

Enumeration headerNames = request.getHeaderNames();

while(headerNames.hasMoreElements())

{

       String headerName = (String)headerNames.nextElement();

       out.print(headerName + " : " + request.getHeader(headerName) + "<br>");

       /*如果要考慮同一個要求標頭名可能出現多次,

       那麼應該用下面的程式碼片段代替上面一行程式碼*/

       /*Enumeration values = request.getHeaders(headerName);

       while(values.hasMoreElements())

        {

              out.print(headerName + " : " + (String)values.nextElement() + "<br>");

       }*/

6、利用Referer要求標頭阻止“盜鏈”

String referrer = request.getHeader("referer");

String sitePart = "http://" + request.getServerName();

if(referrer!=null && referrer.startsWith(sitePart))

{

       //處理正當的下載請求,這裡只進行示意

       out.println("dealing download ...");

}

else

{

       //非法下載請求跳轉到本站的下載說明頁

       RequestDispatcher rd = request.getRequestDispatcher("/down.html");

       rd.forward(request,response);

}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.