javaEE:day9-request和response的轉發、重定向、請求包含小細節

字節輸出流和字符輸出流的共存問題

結論:不能共存(跟get或post方式沒關係)。即在同一個servlet中字符流與字節流不能共存,兩種方法單獨使用都是可以的

另外:如果要用字節流輸出中文,用write(byte[])方法,因爲它的out.print(“晚上好!”);//500錯誤。內部用iso8859-1讀取,已經寫死了,因此中文不行

轉發時,兩個servlet都輸出信息的問題

轉發用

        RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet");
        rd.forward(request, response);

Tomcat對於同response,只輸出一次(把緩存中的內容刷出去)。刷了(close也一樣),流就關閉了,下面的轉發就無法進行了,因爲此時response已經提交了(整個轉發鏈只會響應一次,即提交了) .

詳細知識點見轉發的第三點。

重定向 傳參 訪問順序(doget還是dopost)

重定向用response.sendRedirect("/servletDemo4/servlet/Redir2Servlet"); 參數帶項目名,因爲發給瀏覽器要在tomcat目錄下。

在重定向第一個servlet輸出會被第二個servlet輸出覆蓋,其實是輸出了,但是跳轉的時間太快,人眼不可見。

無論第一個servlet是doget還是dopost,第二個servlet都是doget。因爲轉發過去直接在地址欄輸入路徑,不會在生成表單設置post

重定向,第二個servlet和第一個servlet的request和response都不是同一個對象了,因此無法通過request.setAttribute("age", 22);request.getAttribute("age");傳參,並且,第二個servlet也無法通過request.getParameter("name");從頁面獲取參數。

重定向情況下,如要傳參,則採用地址欄的url的?後面加key=value,多個用&連接。

採用地址欄傳參的方式,在瀏覽器地址欄能看到參數值,因此要注意隱私問題—–加密

轉發只能在站內進行(路徑默認在項目內)而重定向可以在站外進行(如果是在站外,路徑要帶”http://”開頭,站內要帶項目名)如果非要在項目之間(站外)進行跳轉,則必須採用重定向。

轉發 傳參 訪問順序(doget還是dopost)

第一個servlet用dopost第二個servlet也用dopost。第一個servlet用doget第二個servlet也用doget。

第二個servlet中的response會把緩存清空,即將上個servlet的內容清空,然後將此時的servlet的內容寫入緩存,刷出去,顯示到頁面。

tomcat對於同一個servlet只輸出一次(把緩存中的內容刷出去)如果第一個servlet刷了,流就關閉了。只會對response操作會出異常,因爲此時的response已經提交,不能再轉發了。

爲解決上面的問題,我們用傳參在第一個servlet中用request.setAttribute("age", 22);第二個servlet中用request.getAttribute("age"); 通過request容器來進行讀寫,因爲轉發其實是共享同一個request和同一個response對象。在轉發過程中,servlet可以對request進行多次讀取參數。

請求包含 傳參 訪問順序(doget還是dopost)

請求包含用

        RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
        rd.include(request, response);

請求包含的機制可以理解成函數調用,相當於把第二個servlet 中的代碼拷到這裏來執行。

第一個servlet用doget第二個servlet用doget;第一個servlet用dopost第二個servlet也用dopost。

對於請求包含,第二個servlet在執行完之後還會回到第一個servlet的rd.include(request, response);之後。

請求包含與轉發傳參一樣,也是共享同一個request和同一個response對象。不同的是,在請求包含中,如在第一個servlet關流,後面不會出異常,只是後面的不會執行了。如在第一個servlet刷即用out.flush();流不會關閉。請求包含我個人可以理解成是同一個servlet,只是包含的servlet是一個功能模塊而已,所以在同一個servlet中,刷(flush)沒有影響,實質還是在同一個servlet中。

本文完整代碼如下:

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  <body>
     <!-- 
        知識點:
        1字節輸出流和字符輸出流的共存問題
            結論:在一個servlet中字符流與字節流不能共存,兩種方法單獨使用都是可以的
        2轉發時,兩個servlet都輸出信息的問題
            正常的後面一個會覆蓋前面,具體的可以看4.2和4.3
        3重定向 傳參 訪問順序(doGet還是doPost )
            1>方法是:response.sendRedirect() 因爲轉發給瀏覽器,要在tomcat目錄下參數要帶項目名
            2>在重定向第一個servlet輸出後會被第二個servlet輸出覆蓋,其實是輸出了,但是跳轉時間太快,人眼不可見
            3>無論第一個servlet是dopost還是doget,第二個servlet都是doget,因爲轉發過去直接在地址欄輸入路徑。不會再生成表單設置post
            4>重定向第二個servlet和第一個servlet的request和response不是同一個對象,無法用過serAttribute和getAttribute傳參,第二個servlet無法通過getParamer從頁面獲取參數
            5>如要傳參,採用地址欄的url的?後面加key=value 形式進行傳參,多個用&連接。採用地址欄傳參方式
            在瀏覽器地址欄可以看到所傳的參數,因此要注意隱私問題----加密
            6>轉發只能在站內進行(路徑默認在項目內)而重定向可以在站外進行(如果在站外,路徑要帶"http://"開頭,站內要帶項目名)
            如果非要在項目之間(站外)進行跳轉,不虛採用重定向
        4轉發 傳參 訪問順序(doGet還是doPost )
            1>轉發:第一個servlet用doget第二個就是用doget;第一個用dopost第二個也用dopost;
            2>第二個servlet中的response會先把緩存清空,然後將此時的servlet的內容寫到緩存,刷出去顯示到頁面
            3>tomcat對同一個response只會輸出一次,如果第一個servlet刷了即out.flush() 
            那麼流在此就關閉了,後面轉發,操作response都會出異常。因爲此時的response已經提交,不能再轉發了
            4>爲了解決上面問題,我們用傳參來實現:在第一個servlet中setAttribute第二個servlet中getAttribute
            轉發共享同一個request和同一個response對象,在servlet中可以多次讀取參數

        5請求包含 傳參 訪問順序(doGet還是doPost )
            1> 兩個servlet的輸出都有效
            2> request.getRequestDispatcher("").include(request,response);
                因爲是請求包含,還是在項目內,getRequestDispatcher("")的參數可以不帶項目名
                這個include(request,response)可以理解成函數調用,相當於將第二個servlet的代碼拷到這裏來運行。
            3>第一個servlet用doget第二個servlet用doget 第一個servlet用dopost第二個servlet用dopost
            4>對於請求包含 第二個servlet在執行完以後還會回到第一個servlet的include(request,response)後面。
            5>傳參與轉發的傳參一樣,採用setAttribute,getAttribute 。
              dopost方式第二個servlet也能從頁面拿到值。
            不同的是,請求包含在第一個servlet關流,後面不會出異常,在中途調用out.flush() 流不會關閉

      -->
      <h2>1字節輸出流和字符輸出流的共存問題</h2>
      <a href="servlet/OutServlet">字節輸出流和字符輸出流的共存問題</a>
      <form action="servlet/OutServlet" method="post">
          姓名:<input type="text" name="name"/><br/>
         <input type="submit" value="提交"/>
      </form>
      <h2>2轉發時,兩個servlet都輸出信息的問題</h2>
      <a href="servlet/OneServlet">轉發時,兩個servlet都輸出信息的問題</a>
      <form action="servlet/OneServlet" method="post">
          姓名:<input type="text" name="name"/><br/>
         <input type="submit" value="提交"/>
      </form>
      <h2>3重定向 傳參 訪問順序(doGet還是doPost )</h2>
      <a href="servlet/Redir1Servlet">重定向 傳參 訪問順序(doGet還是doPost )</a>
      <form action="servlet/Redir1Servlet" method="post">
          姓名:<input type="text" name="name"/><br/>
         <input type="submit" value="提交"/>
      </form>
      <h2>5請求包含 傳參 訪問順序(doGet還是doPost )</h2>
      <a href="servlet/Include1Servlet">請求包含 傳參 訪問順序(doGet還是doPost )</a>
      <form action="servlet/Include1Servlet" method="post">
          姓名:<input type="text" name="name"/><br/>
         <input type="submit" value="提交"/>
      </form>
  </body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>OutServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.OutServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>OneServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.OneServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>TwoServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.TwoServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Redir1Servlet</servlet-name>
    <servlet-class>cn.hncu.servlet.Redir1Servlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Redir2Servlet</servlet-name>
    <servlet-class>cn.hncu.servlet.Redir2Servlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Include1Servlet</servlet-name>
    <servlet-class>cn.hncu.servlet.Include1Servlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Include2Servlet</servlet-name>
    <servlet-class>cn.hncu.servlet.Include2Servlet</servlet-class>
  </servlet>







  <servlet-mapping>
    <servlet-name>OutServlet</servlet-name>
    <url-pattern>/servlet/OutServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>OneServlet</servlet-name>
    <url-pattern>/servlet/OneServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>TwoServlet</servlet-name>
    <url-pattern>/servlet/TwoServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Redir1Servlet</servlet-name>
    <url-pattern>/servlet/Redir1Servlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Redir2Servlet</servlet-name>
    <url-pattern>/servlet/Redir2Servlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Include1Servlet</servlet-name>
    <url-pattern>/servlet/Include1Servlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Include2Servlet</servlet-name>
    <url-pattern>/servlet/Include2Servlet</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

OutServlet

package cn.hncu.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class OutServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        //字節流
//      ServletOutputStream out = response.getOutputStream();
//      out.println("你好!!!現在是晚上了");
        //上面這種寫法不行,因爲不是iso8859-1格式不認識,out.println這種方法寫死了 只能用iso8859-1
        //我們用下面的方法可以解決中文
//      out.write("你好!!!現在是晚上".getBytes("utf-8"));


        //字符流
        PrintWriter out = response.getWriter();
        out.print("你好,這是晚上寫的代碼");




    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //字節流
//      ServletOutputStream out = response.getOutputStream();
//      out.println("你好!!!現在是晚上了");
        //上面這種寫法不行,因爲不是iso8859-1格式不認識,out.println這種方法寫死了 只能用iso8859-1
        //我們用下面的方法可以解決中文
//      out.write("你好!!!現在是晚上".getBytes("utf-8"));


        //字符流
        PrintWriter out = response.getWriter();
        out.print("你好,這是晚上寫的代碼");
    }

}

OneServlet

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
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("1111get...");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("現在是凌晨兩點18,好累啊");//下面如果不執行flush或close,那麼該句不會輸出,因爲到下一個servlet會把緩存清空
        //out.flush();//Tomcat對於同response,只輸出一次(把緩存中的內容刷出去)。刷了(close也一樣),流就關閉了,下面的轉發就無法進行了,因爲此時response已經提交了(整個轉發鏈只會響應一次,即提交了)

        //傳參
        request.setAttribute("name", "肖答是個傻吊");

        RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet");
        rd.forward(request, response);

    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        System.out.println("111post...");
        out.print("現在是凌晨兩點18,好累啊");//下面如果不執行flush或close,那麼該句不會輸出,因爲到下一個servlet會把緩存清空
        //out.flush();//Tomcat對於同response,只輸出一次(把緩存中的內容刷出去)。刷了(close也一樣),流就關閉了,下面的轉發就無法進行了,因爲此時response已經提交了(整個轉發鏈只會響應一次,即提交了)

        //傳參
        request.setAttribute("name", "肖答是個傻吊");

        RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet");
        rd.forward(request, response);
    }

}

TwoServlet

package cn.hncu.servlet;

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 TwoServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("2222get...");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("現在是凌晨2.20");//第二個servlet會先把緩存中之前的內容清空,然後再把當前servlet的輸出內容寫入緩存,刷出去。
        String nameS1 = (String) request.getAttribute("name");
        String name = request.getParameter("name");
        out.print("<br/>nameServlet1:"+nameS1);
        out.print("<br/>nameIndex:"+name);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("222post...");
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("現在是凌晨2.20");
        String nameS1 = (String) request.getAttribute("name");
        String name = request.getParameter("name");
        out.print("<br/>nameServlet1:"+nameS1);
        out.print("<br/>nameIndex:"+name);
    }

}

Redir1Servlet

package cn.hncu.servlet;

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 Redir1Servlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("1111111servletGet1111");
        response.sendRedirect("/servletDemo4_jun/servlet/Redir2Servlet");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("1111111servlePostt1111");
        String name = request.getParameter("name");
        System.out.println("11111post-param:"+name);
        request.setAttribute("name", "陳威");
//      response.sendRedirect("/servletDemo4_jun/servlet/Redir2Servlet");
        response.sendRedirect("/servletDemo4_jun/servlet/Redir2Servlet?name=cv");
    }

}

Redir2Servlet

package cn.hncu.servlet;

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 Redir2Servlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("2222222222Redir2 get......");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        request.setCharacterEncoding("utf-8");
        String name = request.getParameter("name");
        String nameRq = (String) request.getAttribute("name");
        out.print("name:"+name);
        out.println("<br/>redir1Name:"+nameRq);


    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        System.out.println("2222222222Redir2 Post......");
    }

}

Include1Servlet

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Include1Servlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        out.println("現在是2.59,我好睏");
        request.setAttribute("getName", "張三");
        RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
        rd.include(request, response);
        out.println("<br/>睡你媽逼起來嗨");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        out.println("現在是3.01,我好睏");
        request.setAttribute("postName", "李四");
        RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
        rd.include(request, response);  //可以理解爲函數調用。調完之後還要返回這裏;
        out.println("<br/>睡你媽逼起來嗨");
    }

}

Include2Servlet

package cn.hncu.servlet;

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 Include2Servlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");

        PrintWriter out = response.getWriter();
        out.println("這是include2 get裏的內容");
        String nameS1 = (String) request.getAttribute("getName");
        out.println("Servlet1*---Name:"+nameS1);

    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");

        PrintWriter out = response.getWriter();
        out.println("這是include2 post裏的內容");
        String name = request.getParameter("name");
        out.print("<br/>request-paramer:"+name);
        String nameS1 = (String) request.getAttribute("postName");
        out.println("Servlet1*---Name:"+nameS1);
    }

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