Servlet技術12_HttpServletRequest類

Breaking__Dawn發表於2020-10-02

HttpServletRequest 類有什麼作用:

每次只要有請求進入 Tomcat 伺服器,Tomcat 伺服器就會把請求過來的 HTTP 協議資訊解析好封裝到 Request 物件中。 然後傳遞到 service 方法(doGet 和 doPost)中給我們使用。我們可以通過 HttpServletRequest 物件,獲取到所有請求的 資訊。

HttpServletRequest 類的常用方法:

i. getRequestURI() 獲取請求的資源路徑

ii. getRequestURL() 獲取請求的統一資源定位符(絕對路徑)

iii. getRemoteHost() 獲取客戶端的 ip 地址

iv. getHeader() 獲取請求頭

v. getParameter() 獲取請求的引數

vi. getParameterValues() 獲取請求的引數(多個值的時候使用)

vii. getMethod() 獲取請求的方式 GET 或 POST

viii. setAttribute(key, value); 設定域資料

ix. getAttribute(key); 獲取域資料

x. getRequestDispatcher() 獲取請求轉發物件

常用 API 示例程式碼:

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        i. getRequestURI() 獲取請求的資源路徑
        System.out.println("URI ==> " + req.getRequestURI());

//        ii. getRequestURL() 獲取請求的統一資源定位符(絕對路徑)
        System.out.println("URL ==> " + req.getRequestURL());

        /*  正常情況下,idea中
        使用localhost訪問時,得到的客戶端ip地址是 ===> 127.0.0.1
        使用127.0.0.1訪問時,得到的客戶端ip地址是 ===> 127.0.0.1
        使用真實的電腦ip訪問時,得到的客戶端ip地址是 ===> 真實的客戶端ip地址
         */
//        iii. getRemoteHost() 獲取客戶端的 ip 地址
        System.out.println("客戶端ip ==> " + req.getRemoteHost());

//        iv. getHeader() 獲取請求頭
        System.out.println("請求頭User-Agent ===> " + req.getHeader("User-Agent"));

//        vii. getMethod() 獲取請求的方式 GET 或 POST
        System.out.println("請求的方式:" + req.getMethod());
    }
}

執行結果:
在這裡插入圖片描述

如何獲取請求引數:

建立一個form.html

<!DOCTYPE html>
<html lang="zh_CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/07_servlet/parameterServlet" method="get">
        使用者名稱:<input type="text" name="username" ><br/>
        密碼:<input type="password" name="password" ><br/>
        興趣愛好:<input type="checkbox" name="hobby" value="cpp">C++
        <input type="checkbox" name="hobby" value="java">java
        <input type="checkbox" name="hobby" value="js">JavaScript
        <input type="submit">
    </form>
</body>
</html>

建立一個ParameterServlet.java

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取請求引數
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobby = req.getParameterValues("hobby");

        System.out.println("使用者名稱:" + username);
        System.out.println("密碼:" + password);
        System.out.println("興趣愛好:" + Arrays.asList(hobby));

    }
}

當然,別忘了配置xml。

執行結果:

在這裡插入圖片描述

解決post請求中文亂碼問題:

在使用者名稱框內輸入中文,get請求正常,post請求出現亂碼問題

在這裡插入圖片描述

用一個api就可以了(在獲取引數請求之前才有用

//設定請求體的字符集為UTF-8,從而解決post請求的中文亂碼問題
req.setCharacterEncoding("UTF-8");

這樣,問題就可以得到解決

在這裡插入圖片描述

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //設定請求體的字符集為UTF-8,從而解決post請求的中文亂碼問題
    req.setCharacterEncoding("UTF-8");
    System.out.println("---------doPost-----------");
    //獲取請求引數
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    String[] hobby = req.getParameterValues("hobby");

    System.out.println("使用者名稱:" + username);
    System.out.println("密碼:" + password);
    System.out.println("興趣愛好:" + Arrays.asList(hobby));
}

請求的轉發:

什麼是請求轉發?

請求轉發是指,伺服器收到請求後,從一次資源跳轉到另一個資源的操作叫請求轉發。

在這裡插入圖片描述

Servlet1:

package com.servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取請求引數(辦事的材料)
        String username = req.getParameter("username");
        System.out.println("在Servlet1(櫃檯1)中檢視的引數(材料):" + username);

        //給材料蓋一個章,並傳遞到Servlet2(櫃檯2)檢視
        req.setAttribute("key1","櫃檯1的章");

        //問路:Servlet2(櫃檯2)怎麼走
        /**
         * 請求轉發必須要以 / 打頭,斜槓表示地址為: http://ip:port/工程名/ ,對映到 idea 程式碼的 web 目錄
         */
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");

        //走向Servlet2
        requestDispatcher.forward(req,resp);
    }
}

Servlet2:

package com.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取請求引數(辦事的材料)
        String username = req.getParameter("username");
        System.out.println("在Servlet2(櫃檯2)中檢視的引數(材料):" + username);

        //檢視櫃檯1改的章
        Object key1 = req.getAttribute("key1");
        System.out.println("櫃檯1是否有章:" + key1);

        //處理自己的業務
        System.out.println("Servlet2處理自己的業務");
    }
}

請求轉發的特點:

  1. 瀏覽器位址列沒有變化
  2. 他們是一次請求
  3. 他們共享Request域中的資料
  4. 可以轉發到WEB-INF目錄下(form.html不可以部署到WEB-INF目錄下,但是可以通過請求轉發訪問進來)
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/form.html");

base 標籤的作用:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
    這是web下的index.html<br/>
    <a href="a/b/c.html">a/b/c.html</a>
    <br/>
    <a href="http://localhost:8080/07_servlet/forwardC">請求轉發:a/b/c.html</a>
</body>
</html>

c.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
    這是web/a/b下的c.html<br/>
    <a href="../../index.html">跳回首頁</a>
</body>
</html>

ForwardC.java

public class ForwardC extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("經過了ForwardC程式");
        req.getRequestDispatcher("/a/b/c.html").forward(req,resp);
    }
}

當我們點選index.html中的a標籤進行跳轉的時候,瀏覽器的位址列中的地址是:

http://localhost:8080/07_servlet/a/b/c.html

跳轉回去的a標籤路徑是:

../../index.html

所有相對路徑在工作的時候都會參照當前瀏覽器位址列中的地址來進行跳轉

那麼參照後得到的地址是:

http://localhost:8080/07_servlet/index.html

正確的跳轉路徑

當我們使用請求轉發進行跳轉的時候,瀏覽器位址列中的地址是:

http://localhost:8080/07_servlet/forwardC

跳轉回去的a標籤路徑是:

../../index.html

所有相對路徑在工作的時候都會參照當前瀏覽器位址列中的地址來進行跳轉。

那麼參照後得到的地址是:

http://localhost:8080/index.html

這是錯誤的路徑!

在這裡插入圖片描述

base標籤可以設定當前頁面中所有相對路徑工作時,參照哪個路徑進行跳轉。

修改後的程式碼:

c.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
<!--    base標籤設定頁面相對路徑工作時參照的地址
        href屬性就是引數的地址值-->
    <base href="http://localhost:8080/07_servlet/a/b/c.html">
</head>
<body>
    這是web/a/b下的c.html<br/>
    <a href="../../index.html">跳回首頁</a>
</body>
</html>

說明:

  1. 首先,會檢視有無base標籤,要是有base標籤,他就會忽略掉瀏覽器當前位址列中的地址,而是參考base的值。相當於把地址放到../../index.html前面去了:
http://localhost:8080/07_servlet/a/b/c.html../../index.html

​ 一個../抵消一個資料夾,也就是等於

http://localhost:8080/07_servlet/index.html
  1. base標籤中最後的資源名(c.html)是可以省略的(記住: / 不能省略!)
<base href="http://localhost:8080/07_servlet/a/b/">

Web中的相對路徑和絕對路徑:

在 JavaWeb 中,路徑分為相對路徑絕對路徑兩種:

相對路徑是:

. 表示當前目錄

… 表示上一級目錄

資源名 表示當前目錄/資源名

絕對路徑:

http://ip:port/工程路徑/資源路徑

在實際開發中,路徑都使用絕對路徑,而不簡單的使用相對路徑。

1、絕對路徑

2、base+相對路徑

web 中 / 斜槓的不同意義:

在 web 中 / 斜槓 是一種絕對路徑。

/ 斜槓 如果被瀏覽器解析,得到的地址是:http://ip:port/ http://localhost:8080/

<a href="/">斜槓</a>

/ 斜槓 如果被伺服器解析,得到的地址是:http://ip:port/工程路徑 http://localhost:8080/07_servlet/

  1. <url-pattern>/servlet1</url-pattern>
  2. servletContext.getRealPath(“/”);
  3. request.getRequestDispatcher(“/”);

特殊情況: response.sendRediect(“/”); 把斜槓傳送給瀏覽器解析。得到 http://ip:port/

相關文章