天天看點

請求包含,轉發,重定向的差別

當浏覽器請求一個jsp,servlet時,會調用相應的service方法

注意:在同一個servlet中無法   位元組流和字元流共存,伺服器對于請求隻響應一次給浏覽器的資訊,隻會選擇一個流一次性輸出資訊,擷取不同流會出異常

            在輸出中文時,位元組流需要write(“”.getBytes("編碼")),print()隻能輸出ISO8859-1支援的字元,其他字元出異常

                                        字元流,隻要設定了協定頭即可輸出中文

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		//1用位元組輸出流向用戶端寫資訊
		ServletOutputStream out = response.getOutputStream();//擷取位元組輸出流
		out.print("Hello");//OK
		//out.print("晚上好!");//500錯誤。内部用iso8859-1讀取,已經寫死了,是以中文不行
		out.write("晚上好!".getBytes("utf-8"));//如果要用位元組流輸出中文,用write(byte[])方法
				
		
		//2用字元輸出流向用戶端寫資訊
		PrintWriter out2 = response.getWriter();
		out2.print("Hello, 晚上好!");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("post........");
		response.setContentType("text/html;charset=utf-8");
		//1用位元組輸出流向用戶端寫資訊
		ServletOutputStream out = response.getOutputStream();//擷取位元組輸出流
		out.print("Hello");//OK
		//out.print("晚上好!");//500錯誤。内部用iso8859-1讀取,已經寫死了,是以中文不行
		out.write("晚上好!".getBytes("utf-8"));//如果要用位元組流輸出中文,用write(byte[])方法
				
		
		//2用字元輸出流向用戶端寫資訊
		PrintWriter out2 = response.getWriter();
		out2.print("Hello, 晚上好!");
	}
           

位元組輸出流和字元輸出流的共存問題---不能共存(跟get或post方式沒關系)。即:在同一個servlet響應中,不能同時采兩種輸出流。

一:站外請求通路

        隻能進行重定向的方式,以get方式通路:

        1)無論第一個是doGet還是doPost,第二個走的都是doGet

        2)傳參:第二個servlet中的request和第一個是完全不同的對象,是以無法通過:request.setAttribute()和request.getAttribute() 實作傳參。

        3)第二個servlet中是無法通過request.getParameter()的方式擷取頁面送出的參數資料

        4)重定向方式下,如果要進行傳參,可采用:在位址欄的url後添加類似如下的格式傳參:?name=Jack&age=23

                      注意,采用位址欄url傳參的方式,在浏覽器位址欄是能夠看到的,是以要注意隐私(安全)問題---如果有隐私參數,那麼要加密!!!

        5)轉發隻能在站内進行(路徑預設在項目内,即路徑不用帶項目名),重定向可以在站外進行(如果是站外路徑要帶“http://”開頭,站内路徑要帶項目名)。如果非要項目之間(站

         外) 進行跳轉,那麼必須要選擇重定向。

throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("111111111111");//無效的輸出
		
		response.sendRedirect("/servletDemo4/servlet/Redir2Servlet");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("111111111111");//無效的輸出
		
		String name = request.getParameter("name");
		System.out.println("111para-name:"+name);
		//request.setAttribute("age", 22);//無效的屬性設定
		//response.sendRedirect("/servletDemo4/servlet/Redir2Servlet");
		response.sendRedirect("/servletDemo4/servlet/Redir2Servlet?name=Jack&age=23");//隻能以位址欄傳輸
	}
           

二:站内請求

           除了可以重定向外,還有轉發及包含

       一:請求轉發:

              轉發:傳參,通路順序(doGet還是doPost) ---轉發是共享同一個request和同一個response對象的

            1)第一個是doGet,第二個走的也是doGet

            2)第一個是doPost,第二個走的也是doPost

            3)傳參:可以通過request.setAttribute()設定,通過request.getAttribute()擷取 ---doGet或doPost都一樣

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("晚上好....");//下面如果不執行flush或close,那麼該句不會輸出,因為到下一個servlet會把緩存清空
		//out.flush();//Tomcat對于同response,隻輸出一次(把緩存中的内容刷出去)。刷了(close也一樣),流就關閉了,下面的轉發就無法進行了,因為此時response已經送出了(整個轉發鍊隻會響應一次,即送出了)
		
		//傳參--設定屬性(隻要key不同,随便存幾個)----放入request對象
		request.setAttribute("name", "Jack-Onservlet");
		
		String name2 = (String) request.getParameter("name");
		System.out.println("1111para-name"+name2);
		
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet");
		rd.forward(request, response);
	}
           

      二:請求包含

         請求包含:傳參,通路順序(doGet還是doPost)

         1)兩個servlet的輸出都有效!---中途調用flush,流不會關閉,後續的輸出都會執行。如果在第一個servlet中執行了out.close(),那麼後續的輸出(無論是第一還是第二個  

           servlet)都不會執行,但程式不會出異常!!!!

         2)第一個是doGet,第二個走的也是doGet

         3)第一個是doPost,第二個走的也是doPost

         4)對于請求包含,第二個servlet在執行完之後,還會回到第一個servlet的rd.include()這行代碼之後。

         5)傳參方面,和轉發是完全一樣的,因為都是共享同一個request和同一個response.

         6)頁面輸出時,注意html标簽不要輸出沖突,如:在第一個servlet中輸出了“<html><body>”和“</body></html>”,同時在第二個servlet中也輸出這些标記。這樣會出現html

             标記嵌套沖突!!

         ※重定向和轉發:跳轉之後不會回到原來的那個servlet中。

         而“請求轉發”在跳轉之後會回到原來servlet的“rd.include()”這句代碼之後繼續執行。

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html><body>");
		out.println("Include1111111..doGet...");
		
		//傳參:和轉發一樣
		request.setAttribute("age", 25);
		
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
		rd.include(request, response);//它的機制可了解成函數調用。相當于把第二個servlet的doGet()方法中的代碼拷到這裡來運作。
		out.println("<br/>Include1111111..doGet...請求包含之後");
		
		out.print("</body></html>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("Include1111111..doPost...");
		
		//傳參:和轉發一樣
		request.setAttribute("age", 25);
		out.flush();
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
		rd.include(request, response);
		out.println("<br/>Include1111111..doPost...請求包含之後");
	}