請求包含,轉發,重定向的區別
當瀏覽器請求一個jsp,servlet時,會呼叫相應的service方法
注意:在同一個servlet中無法 位元組流和字元流共存,伺服器對於請求只響應一次給瀏覽器的資訊,只會選擇一個流一次性輸出資訊,獲取不同流會出異常
在輸出中文時,位元組流需要write(“”.getBytes("編碼")),print()只能輸出ISO8859-1支援的字元,其他字元出異常
字元流,只要設定了協議頭即可輸出中文
位元組輸出流和字元輸出流的共存問題---不能共存(跟get或post方式沒關係)。即:在同一個servlet響應中,不能同時採兩種輸出流。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方式訪問:
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...請求包含之後");
}