javaWeb03-請求轉發和請求重定向【包含編碼格式與路徑問題】

zwGitOne發表於2023-02-11

本文主要講述javaWeb的請求轉發和請求重定向的區別

一. 請求轉發

1. 圖解

vip

2. 程式碼示例

  Servlet1的程式碼示例如下

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1收到請求");
        req.setAttribute("key","Servlet1蓋的章");
        req.getRequestDispatcher("/servlet2").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

  Servlet2的程式碼示例如下

public class Servlet2 extends HttpServlet {
    @Override
    // 請求轉發,處理的是同一個請求
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object key = req.getAttribute("key");
        System.out.println("Servlet2收到了" + key);
        resp.getWriter().write("Servlet2響應的內容");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

  瀏覽器收到響應,顯示結果如下

vip

 

  思考1

  響應response沒有設定編碼規則,導致預設的編碼規則不支援中文字元,驗證如下

public class Servlet2 extends HttpServlet {
    @Override
    // 請求轉發,處理的是同一個請求
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object key = req.getAttribute("key");
        System.out.println("Servlet2收到了" + key);
        System.out.println(resp.getCharacterEncoding());
        resp.getWriter().write("Servlet2響應的內容");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

  tomcat日誌如下

Servlet1收到請求
Servlet2收到了Servlet1蓋的章
ISO-8859-1

  由此看出,字符集是ISO-8859-1應該不支援中文字元

  將resp的字符集設定為utf-8,宣告如下

resp.setCharacterEncoding("utf-8");

  瀏覽器收到響應,顯示結果如下,仍是亂碼

vip

  思考2

  resp響應設定了字符集utf-8,但是瀏覽器編碼格式不是utf-8,而是windos-1252。字符集不相同,導致亂碼

  由思考和思考2,引出問題:如何保證瀏覽器和響應resp的字符集相同呢?

  首先介紹Content-Type

vip

  解決方法

  Servlet2宣告如下

public class Servlet2 extends HttpServlet {
    @Override
    // 請求轉發,處理的是同一個請求
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object key = req.getAttribute("key");
        System.out.println("Servlet2收到了" + key);
        // 解決瀏覽器與resp響應的編碼格式不一致問題:
        // 方式一:
        resp.setHeader("Content-Type","text/html;charset=utf-8");
        // 方式二:
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("Servlet2響應的內容");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

3. 總結

  ① 請求轉發,一直是同一個請求【請求的資料可以共享】

  ② 在resp響應瀏覽器內容時,如果有中文字元,則在響應之前,需要設定content-type,即 resp.setContentType("text/html;charset=utf-8");

二. 請求重定向

1. 圖解

vip

2. 程式碼示例

  Servlet1的程式碼示例如下

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1收到請求");
        System.out.println("Servlet1請求重定向給Servlet2");
        resp.sendRedirect("/servlet2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

  Servlet2的程式碼示例如下

public class Servlet2 extends HttpServlet {
    @Override
    // 請求轉發,處理的是同一個請求
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet2收到請求");
        System.out.println("請求路徑為: ");
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

  瀏覽器收到響應,結果如下

vip

  思考

  請求重定向的路徑寫的不對,下面解釋一下 " / "

  在瀏覽器中," / "是指 http://localhost:8080,即http://ip地址:埠號

  在web專案中," / "是指http://localhost:8080/javaWeb03,即http://ip地址:埠號/專案名稱 

  解決方法

  Servlet1宣告如下

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1收到請求");
        System.out.println("Servlet1請求重定向給Servlet2");// 解決方式1:相對路徑
        resp.sendRedirect("/javaWeb02/servlet2");
        // 解決方式2:絕對路徑
        resp.sendRedirect("http://localhost:8080/javaWeb02/servlet2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

  tomcat日誌結果如下

Servlet1收到請求
Servlet1請求重定向給Servlet2
Servlet2收到請求
請求路徑為: 
http://localhost:8080/javaWeb02/servlet2

3. 總結

  ① 注意瀏覽器和web專案中的" / "的不同含義;

  ② 請求重定向是瀏覽器向伺服器發了兩次請求

  

 

相關文章