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

2023-02-11 15:01:27

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

一. 請求轉發

1. 圖解

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 {

    }
}

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

 

  思考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");

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

  思考2

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

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

  首先介紹Content-Type

  解決方法

  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. 圖解

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 {

    }
}

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

  思考

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

  在瀏覽器中," / "是指 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專案中的" / "的不同含義;

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