1. 程式人生 > >請求包含,轉發,重定向的區別

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

當瀏覽器請求一個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...請求包含之後");
	}