HTTP與request

HTTP協議

  1. HTTP:超文本傳輸協議,定義了瀏覽器與服務器之間數據傳輸的格式;簡而言之,就是一種在web中傳輸數據的格式。
  2. HTTP協議組成:
    1. 請求報文:請求行,請求頭,請求體;
      1. 請求行:請求報文中的第一行數據,包括請求方式,URL,協議/版本;
      2. 請求頭:以鍵值對的數據格式,給服務器傳輸數據。常用的請求頭:user-agent,cookie;
      3. 請求體:get請求:沒有請求體;post請求:請求體傳遞請求參數;
      4. GET:向特定的資源發出請求(a href="servlet"標籤/js location.href=“servlet”)
      5. POST向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的創建和/或已有資源的修改
    2. 響應報文:響應行,響應頭,響應體;

百科:HTTP協議

超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲廣泛的一種網絡協議。
所有的WWW文件都必須遵守這個標準。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。
1960年美國人TedNelson構思了一種通過計算機處理文本信息的方法,並稱之爲超文本(hypertext),這成爲了HTTP超文本傳輸協議標準架構的發展根基。
Ted Nelson組織協調萬維網協會(World Wide Web Consortium)和互聯網工程工作小組(Internet Engineering Task Force )共同合作研究,最終發佈了一系列的RFC,其中著名的RFC 2616定義了HTTP 1.1
協議版本:
HTTP/1.0,發送請求,創建一次連接,獲得一個web資源,連接斷開。
HTTP/1.1,發送請求,創建一次連接,獲得多個web資源,連接斷開。

GET和POST請求區別
GET請求
請求行直接傳遞請求參數
將請求參數追加在URL後面,不安全。例如:form.html?username=jack&username=1234
URL長度限制GET請求方式的數據大小,不可以傳輸數據量較大或者非文本數據
請求體裏面沒有內容
POST請求
請求參數以請求體形式發送給服務器,數據傳輸安全
請求數據可以爲非文本數據,可以傳輸數據量較大的數據
只有表單設置爲method=”post”纔是post請求.其他的都是get請求, 常見GET請求:地址欄直接訪問、< a href=””>、< img src=””> 等

瀏覽器和服務器是以固定的格式進行通信的,採取的HTTP協議的請求協議。瀏覽器通過請求協議,將數據傳送到服務器中。

request與請求數據的獲取

通過request對象可以獲取請求攜帶的數據,分別獲取請求行、請求頭、請求體中的數據,從而獲取用戶提交的數據,進行業務邏輯的處理。
什麼是HttpServletRequest
HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求中的所有信息都封裝在這個對象中,我們通過這個對象的方法,可以獲得客戶這些信息。
HTTPServletRequest的作用
通過Request對象進行的常用操作:

  1. 獲取請求行信息:請求方式,url和HTTP版本;
  2. 獲取去請求頭信息:瀏覽器類型,cookie等;
  3. 獲取請求參數:url後面拼接的參數或者請求體中提交的參數;

獲取請求行信息
請求行包括:請求方式,url和協議版本。HttpServletRequest對象提供了以下方法來獲取這些信息。

  • String getMethod():獲取去請求方式的類型。
  • StringBuffer getRequestURL():獲取客戶端發出請求完整URL。
  • String getRemoteAddr():獲取IP地址。
  • String getProtocol():獲取當前協議的名稱和版本。

代碼:

@WebServlet("/rowServlet")
public class RowServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //請求行API
        //獲取請求協議版本號
        String protocol = request.getProtocol();
        System.out.println("protocol = " + protocol);

        //獲取請求方式
        String method = request.getMethod();
        System.out.println("method = " + method);

        //IP地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println("remoteAddr = " + remoteAddr);

        //獲取URL
        StringBuffer requestURL = request.getRequestURL();
        System.out.println("requestURL = " + requestURL);
    }
}

獲取請求頭信息
瀏覽器的請求頭信息是由很多:關鍵字:值 形式的數據組成的。HttpServletRequest對象給我們提供了兩個方法用來獲取請求的頭信息。

  • String getHeader(String name):根據請求頭的k關鍵字獲取請求頭信息。
  • Enumeration getHeaderNames():返回此請求包含的所有頭信息的枚舉。

請求頭的k關鍵字如下表所示:

在這裏插入圖片描述
代碼:

@WebServlet("/headerServlet")
public class HeaderServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        //獲取請求頭API
        String header = request.getHeader("User-Agent");
        System.out.println("header = " + header);
        //獲取所有key
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            System.out.println(headerNames.nextElement());
        }
    }
}

獲取請求體(請求參數)(很重要)

學習了請求航和請求頭的內容,然後就是請求體了,在請求體中,包含的是用戶通過瀏覽器發送的請求參數,因此,我們主要學習的就是獲取請求參數的方法。
回顧一下瀏覽器中的請求數據是怎麼提交的。
get請求:提交的數據是拼接在url後面。
post請求:數據是在請求體中發送到後臺的。
兩者的格式都是name=value

獲取請求參數的方法

  • String getParameter(String name):getParameter獲得指定參數名對應的值。如果沒有返回null,如果有多個則獲取第一個。例如username=jack。
  • String[ ] getParameterValues(name):getParameterValues[ ]獲取請求數據key相同的多個數據。
  • request.getParameterMap():獲取所有表單數據。

代碼:
編寫用戶表單,提供表單字段:username、password、hobby、以post方式提交。
(由於沒有設置utf-8,大家在提交數據時,儘量別用中文)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="requestServlet" method="post">

    用戶名:<input type="text" name="username"/><br/>

    密碼:<input type="text" name="password"/><br/>

    愛好:<input type="checkbox" name="hobby"value="smoking"/> 抽菸

    <input type="checkbox" name="hobby"value="drinking"/> 喝酒

    <input type="checkbox" name="hobby" value="tangtou"/> 燙頭  <br/>

    學歷:<select name="education">

        <option value="gaozhong">高中</option>

        <option value="dazhuan">大專</option>

        <option value="benke">本科</option>

    </select><br>

    <input type="submit"value="post提交" />
    </form>
</body>
</html>
@WebServlet("/requestServlet")
public class RequestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //獲取用戶提交的所有數據
        String username=request.getParameter("username");
        System.out.println("用戶提交的所有數據:useranme:"+username);

        String password=request.getParameter("password");
        System.out.println("-------------------password:"+password);

        String[] hobbies=request.getParameterValues("hobby");
        System.out.println("-------------------hobby:"+Arrays.toString(hobbies));

        //可以獲取表單提交所有信息
        Map<String,String[]> parameterMap=request.getParameterMap();
        Collection<String[]> values=parameterMap.values();
        for (String[] value:values){
            System.out.println(Arrays.toString(value));
        }
    }
}

request作用域
request的生命週期

【一次請求和響應的完整流程】
1、瀏覽器向servlet發送請求
2、tomcat收到請求後,創建Request和Response兩個對象,並將請求數據封裝到request對象中,然後傳遞給Servlet
3、Servlet接收到請求後,調用request提供的方法。處理瀏覽器的請求信息,然後通過Response返回信息
4、tomcat將業務邏輯處理的結果,返回給瀏覽器。
5、瀏覽器接收到返回消息後,tomcat銷燬Request和Response兩個對象,同時銷燬這兩個對象所獲得的信息。

  • 創建:瀏覽器給服務器發送請求後,tomcat創建request對象封裝請求數據;
  • 銷燬:服務器給瀏覽器響應信息結束後銷燬;

特點:瀏覽器每次給服務器發送請求,服務器都會爲這次請求創建一個request對象。

request域對象
request域對象,一個存儲數據的區域對象.是把request當成一個容器來存儲數據,request域存儲數據主要是用於在兩個servlet之間傳遞數據。request作爲域對象,常用的方法如下:

  • void setAttribute(String name,Object o):往request域中設置值。
  • Object getAttribute(String name):從request域中取值。
  • void removeAttribute(String name):從request域中刪除值。

演示:
創建一個servlet
往request域中設置值
從request域中取值
將request域中的值移除

@WebServlet("/value")
public class ValueServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用request對象存儲值
        request.setAttribute("key","關曉彤");
        //根據KEY  來獲取值
        String key = (String) request.getAttribute("key");
        System.out.println("美女 = " + key);

        //移除值
        request.removeAttribute("key");
        Object key1 = request.getAttribute("key");
        if (key1==null){
            System.out.println("刪除成功");
        }
    }
}

注意:getParameter()方法和getAttribute()方法的區別

  1. getParameter()方法獲取的是瀏覽器提交的數據(多是表單提交的數據);
  2. getAttribute()方法是獲取request域中的數據(通過request.setAttribute()設置的值;

請求轉發:
我們之前使用到的請求都是從頁面發出,然後請求到Servlet。其實,在Servlet中。請求也可以從一個Servlet發起,然後請求到另一個Servlet或靜態頁面。這項技術叫做請求轉發。
請求轉發需要藉助以下兩個方法實現:

  • RequestDispatcher getRequestDispatcher(String path):獲取請求轉發器(request對象方法)
  • void forward(ServletRequest request, ServletResponse response):將請求轉發到另一個資源(Servlet)上

演示:請求轉發
需求:
從一個Servlet轉發到另一個Servlet;
從一個Servlet轉發到一個靜態頁面;

@WebServlet("/twoServlet")
public class TwoServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        doGet(req, resp);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        //通過request域對象設置值
        //使用轉發 其他servlet
        req.setAttribute("name","xiaoming");
        //避免代碼臃腫
        //獲取請求轉發器
        req.getRequestDispatcher("/thrServlet").forward(req,resp);
    }
}

@WebServlet("/thrServlet")
public class ThrServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doGet(req, resp);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //獲取數據,進行處理
        String name=(String)req.getAttribute("name");
        System.out.println("name="+name);
    }
}

從servlet轉發到html

@WebServlet("/oneServlet")
public class OneServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //靜態資源
        //使用轉發
        req.getRequestDispatcher("/one.html").forward(req,resp);
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>關曉彤</h1>
</body>
</html>

轉發:

  • 轉發是服務器內部的跳轉行爲;
  • 從一個Servlet轉發到另一個資源(靜態或者動態),能夠實現跳轉,但是瀏覽器地址欄沒有改變,因爲對瀏覽器來說,本質上只有一個請求。
  • 請求轉發的作用:共享request域中的數據。

登錄案例

需求:

  • 設計登錄表單頁面,數據庫用戶表user (字段 id,userName,password),通過sql手動插入若干用戶數據記錄。
  • 基於form表單數據提交,將客戶端用戶輸入的賬號和密碼發送給服務器Servlet
  • Servlet獲取表單提交的賬號和密碼數據,基於所學的JdbcTemplate直接訪問數據庫t_user表,查詢賬號和密碼是否正確
  • 根據數據庫查詢的結果,如果賬號密碼錯誤,轉發到error.html。賬號密碼都正確轉發到success.html頁面。

在這裏插入圖片描述搭建環境:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章