搜尋 伺服器處理請求

dead_lee發表於2021-09-09

一、request

request封裝了客戶端所有的請求
request是Servlet.service()方法的一個引數,型別為javax.servlet.http.HttpServletRequest。

request物件的功能

  • 1)獲取Http的請求頭

    • String getHeader(String name)
      獲取指定名稱的請求頭

    • int getIntHeader(String name)
      獲取值為int型別的請求頭

    • Enumeration getHeaderNames()
      獲取所有請求頭名稱

小栗子:
獲取客戶端的IP地址、獲取請求方式、獲取User-Agent,得到客戶端的資訊(作業系統 瀏覽器)。

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;/**
 * 獲取客戶端的IP地址、獲取請求方式、獲取User-Agent,得到客戶端的資訊(作業系統 瀏覽器)。
 *
 */public class AServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String addr = request.getRemoteAddr();//獲取客戶端的IP地址
        
        response.sendRedirect("");        if(true) return;
        
        System.out.println("IP: " + addr);
        System.out.println("請求方式:" + request.getMethod());//獲取請求方式
        String userAgent = request.getHeader("User-Agent");//獲取名為User-Agent的請求頭!
        // 是否包含Chrome,如果包含,說明使用者使用的是google瀏覽器
        if(userAgent.toLowerCase().contains("chrome")) {
            System.out.println("您好:" + addr + ", 你用的是谷歌");
        } else if(userAgent.toLowerCase().contains("firefox")) {
            System.out.println("您好:" + addr + ", 你用的是火狐");
        } else if(userAgent.toLowerCase().contains("msie")) {
            System.out.println("您好:" + addr + ", 你用的是IE");
        }
    }
}

圖片描述

執行結果

  • 2)獲取請求url
    例如地址:

    • String getScheme()
      獲取協議
      http

    • String getServerName()
      獲取伺服器名
      localhost

    • String getServerPort()
      獲取伺服器埠
      8080

    • String getContextPath()
      獲取專案名
      /visitCount

    • String getServletPath()
      獲取Servlet路徑
      /AServlet

    • String getQueryString()
      獲取引數部分,即問號後面的部分
      username=xxx&password=yyy

    • String getRequestURI()
      獲取請求URI,即專案名+Servlet路徑
      /visitCount/AServlet

    • String getRequestURL()
      獲取請求URL,即不包含引數的整個請求路徑

圖片描述

獲取請求url

  • 3)獲取請求引數
    請求引數是由客戶端傳送給伺服器的
    有可能是在請求體中(POST),也可能是在URL之後(GET)

    • String getParameter(String name)
      獲取指定名稱的請求引數值,適用於單值請求引數

    • String[] getParameterValues(String name)
      獲取指定名稱的請求引數值,適用於多值請求引數

    • Enumeration<String> getParameterNames()
      獲取所有請求引數名稱

    • Map<String,String[]> getParameterMap()
      獲取所有請求引數,其中key為引數名,value為引數值。

  • 4)請求轉發和請求包含
    在一個請求鏈中,涉及到多個Servlet
    RequestDispatcher rd = request.getRequestDispatcher("/MyServlet");
    使用request獲取RequestDispatcher物件,方法的引數是被轉發或包含的Servlet的Servlet路徑

    • 請求轉發
      rd.forward(request,response);

    • 請求包含
      rd.include(request,response);

在什麼時候使用請求轉發和請求包含
需要多個Servlet協作才能完成,需要在一個Servlet跳到另一個Servlet。

  • 一個請求跨多個Servlet,需要使用轉發和包含。

  • 請求轉發:由下一個Servlet完成響應體!當前Servlet可以設定響應頭!(針對第一個Servlet來說:留頭不留體)

  • 請求包含:由兩個Servlet共同未完成響應體!(都留)

  • 無論是請求轉發還是請求包含,都在一個請求範圍內,使用同一個request和response。

小栗子:請求轉發
OneServlet.java

package cn.itcast.servlet.forward;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 OneServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("OneServlet...");
        response.setHeader("aaa", "AAA");//設定響應頭
        response.getWriter().print("a");//設定響應體//如果要轉發給其他頁面做,就不要在本頁面做太多動作,不然會拋異常//如果執行下面註釋的程式碼就會拋異常//      for(int i = 0; i < 1024 * 24 + 1; i++) {//          response.getWriter().print("a");//設定響應體//      }

        //請求轉發
        request.getRequestDispatcher("/TwoServlet").forward(request, response);
    }
}//只保留請求頭內容顯示TwoServlet.java的內容
  • 5)request域
    在兩個Servlet中透過轉發或包含來完成傳遞中會用到request域
    request是Servlet三大域物件之一。
    request,session,application。這三大域都有一下幾種方法

    • void setAttribute(String name, Object value)
      用來儲存一個物件,也可以稱之為儲存一個域屬性

    • Object getAttribute(String name)
      用來獲取request中的資料,當前在獲取之前需要先去儲存才行

    • void removeAttribute(String name)
      用來移除request中的域屬性,如果引數name指定的域屬性不存在,那麼本方法什麼都不做

    • Enumeration getAttributeNames()
      獲取所有域屬性的名稱

同一請求範圍內使用request.setAttribute()、request.getAttribute()來傳值!前一個Servlet呼叫setAttribute()儲存值,後一個Servlet呼叫getAttribute()獲取值。

  • 6)請求轉發和重定向的區別

    • 請求轉發是一個請求一次響應,而重定向是兩次請求兩次響應

    • 請求轉發位址列不變化,而重定向會顯示後一個請求的地址

    • 請求轉發只能轉發到本專案其他Servlet,而重定向不只能重定向到本專案的其他Servlet,還能定向到其他專案

    • 請求轉發是伺服器端行為,只需給出轉發的Servlet路徑,而重定向需要給出requestURI,即包含專案名!

    • 轉發的效率比重定向的效率高

    • 需要位址列發生變化,那麼使用重定向!

    • 需要在下一個Servlet中獲取request域中的資料,要使用轉發!

二、response

response是Servlet.service()方法的一個引數,型別為javax.servlet.http.HttpServletResponse。

ServletResponse和HttpServletResponse的區別
ServletResponse是與協議無關的型別
HttpServletResponse是與協議相關的型別

1.response物件的功能

  • 1)傳送狀態碼
    狀態碼:200表示成功、302表示重定向、404表示客戶端錯(訪問的資源不存在)、500表示伺服器端錯

    • sendError(int sc)
      傳送錯誤狀態碼,eg:404,500

    • sendError(int sc, String msg)
      傳送錯誤狀態碼,攜帶一個錯誤資訊

    • setStatus(int sc)
      傳送成功的狀態碼,可以用來傳送302

小栗子:傳送404

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;/**
 * 傳送404狀態碼
 *
 */public class AServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.sendError(404, "您訪問的資源存在,就不給你看!");
    }
}
  • 2)設定響應頭資訊
    響應頭:Content-Type、Refresh、Location等等
    頭就是鍵值對

    • setHeader(String name, String value)(常用)
      適用於單值的響應頭,
      例如:response.setHeader("aaa", "AAA");
      名字叫aaa,值是AAA

    • addHeader(String name, String value)
      適用於多值的響應頭
      例如:
      response.addHeader("aaa", "A");
      response.addHeader("aaa", "AA");
      response.addHeader("aaa", "AAA");

    • setIntHeader(String name, int value)
      適用於單值的int型別的響應頭
      例如:response.setIntHeader("Content-Length", 888);

    • addIntHeader(String name, int value)
      適用於多值的int型別的響應頭

    • setDateHeader(String name, long value)
      適用於單值的毫秒型別的響應頭
      例如:response.setDateHeader("expires", 1000 * 60 * 60 * 24);

    • addDateHeader(String name, long value)
      適用於多值的毫秒型別的響應頭

小栗子:

①傳送302,設定Location頭,完成重定向

圖片描述

重定向思路圖

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;/**
 * 重定向!
 *
 * 使用者請求BServlet,然後BServlet響應302,給出Location頭
 */public class BServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("BServlet");        
        /*
         * 重定向:
         * 1. 設定Location
         * 2. 傳送302狀態碼
         *///      response.setHeader("Location", "/text/CServlet");//                                     專案名/Servlet路徑(請求url)//      response.setStatus(302);
        
        //快捷的重定向方法
        response.sendRedirect("/text/CServlet");
    }
}



作者:樂樂親麼麼噠
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4686/viewspace-2818392/,如需轉載,請註明出處,否則將追究法律責任。

相關文章