1. 四大作用域對象
作用域對象存在的意義: 爲了在多個web組件之間傳遞和共享數據。
public class TestServletScope extends HttpServlet { //作用域經典案例測試 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. request 表示當前請求的範圍 if(request.getAttribute("count")==null) { request.setAttribute("count", 1); }else { request.setAttribute("count", (Integer)(request.getAttribute("count"))+1); } //2. session 表示當前會話的範圍 HttpSession session = request.getSession(); if(session.getAttribute("count")==null) { session.setAttribute("count", 1); }else { session.setAttribute("count", (Integer)(session.getAttribute("count"))+1); } //3. application 表示當前應用的範圍 ServletContext application = request.getServletContext(); if(application.getAttribute("count")==null) { application.setAttribute("count", 1); }else { application.setAttribute("count", (Integer)(application.getAttribute("count"))+1); } //請求重定向 request.getRequestDispatcher("result").forward(request, response); } }
public class ResultServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request int count1 = (Integer)request.getAttribute("count"); response.getWriter().println("request:"+count1); //session HttpSession session = request.getSession(); int count2 = (Integer)session.getAttribute("count"); response.getWriter().println("session:"+count2); //application ServletContext app = request.getServletContext(); int count3 = (Integer)app.getAttribute("count"); response.getWriter().println("application:"+count3); } }
運行結果:request值一直不變。當重新請求 session值加一,,關閉瀏覽器後 session值變爲1 . 只有關閉tomcat ,application 才變成1,不然重新請求一直遞增。
2. 請求轉發forward和URL重定向的區別?
請求轉發:request.getRequestDispatcher("login.jsp").forward(request, response);
瀏覽器的請求發送給組件1,組件1經過一些處理之後,將request和response對象“傳遞”給組件2,由組件2繼續處理,然後輸出響應(當然,也可以繼續向其他組件“傳遞”),這個傳遞的過程稱之爲“轉發”。
整個過程只涉及一次瀏覽器和服務器之間的“請求-響應”,轉發過程中的組件共享同一個請求(request)和響應(response)對象。
特點:
1. 轉發過程中瀏覽器地址欄路徑沒變,共享同一個請求對象,在請求中共享數據,響應由最後一個決定。
2. 只能夠訪問當前應用中的資源,包括WEB-INF中的資源,不能夠跨域跳轉(老師我想跳轉到源代碼官網去看視頻...)
3.一般用於用戶登陸的時候,根據角色轉發到相應的模塊.
4. 疑問: 既然可以訪問WEB-INF中的資源了,那怎麼之前又說放在裏安全呢?
a) 程序沒有提供的路徑就不能夠訪問;
b) 在跳轉之前可以做權限判斷
重定向:response.sendRedirect("login.jsp");
是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以地址欄顯示的是新的URL.
特點:
1. 瀏覽器中地址會變,發送了兩個請求,相當於訪問了兩次。
2. 因爲是不同的請求,所以不能夠共享請求中的數據,最終的響應是由最後一個Servlet決定。
3. 可以跨域訪問資源(嘗試訪問itsource.cn),不能夠訪問WEB-INF中的資源
4.一般用於用戶註銷時返回主頁面或跳轉到其它的網站等
3.無狀態的HTTP
Http:表示超文本的傳輸協議 。特點:無狀態的---多個請求之間,不會去共享信息。
什麼是會話?
可簡單理解爲:用戶開一個瀏覽器,訪問某一個web站點,在這個站點點擊多個超鏈接,訪問服務器多個web資源,然後關閉瀏覽器,整個過程稱之爲一次會話。
會話跟蹤
HTTP是無狀態協議,沒有記憶力,不知道哪一個客戶端請求了自己,每個請求之間無法共享數據。這就無法知道會話什麼時候開始,什麼時候結束,也無法確定發出請求的用戶身份。
在一次會話中多次請求共享數據即會話跟蹤技術.
解決HTTP無狀態的問題:參數傳遞
把我們需要保持狀態的數據在每次跳轉的時候都傳到另一個頁面上去。
這種方式有天生的缺陷:
1. 跳轉的網頁過多,傳值麻煩,因爲地址欄參數是有限制的且可見,所以傳值數據有限,安全性低。
2. 不可以傳遞對象
怎麼辦? 使用Cookie或者Session。
4. 談談cookie
4.1 cookie的原理:
Cookie是由服務器端生成,發送瀏覽器,瀏覽器會將Cookie的key/value保存到某個目錄下的文本文件內,當瀏覽器再請求服務器時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器通過檢查該Cookie來獲取用戶狀態。(前提是瀏覽器設置爲啓用cookie)。
4.2 添加cookie
獲取客戶端的Cookie時,只能獲取name與value屬性,其它屬性都不會被提交。
Cookie c = new Cookie("username","peter");// 新建一個Cookie對象 c.setMaxAge(24*60*60); // 設置過期時間1天,以秒爲單位 response.addCookie(c); // 保存cookie到客戶端
4.3 刪除cookie
刪除某個Cookie時,只需要新建一個只有maxAge和value不一樣的同名Cookie,然後添加到response中覆蓋原來的Cookie
Cookie cookie = new Cookie("username","peter");// 新建Cookie cookie.setMaxAge(0); // 設置生命週期爲0,表示將要刪除 response.addCookie(cookie); // 執行添加後就從response裏刪除了
4.4 修改cookie
1. 修改某個Cookie時,只需要新建一個只有value屬性不一樣的同名Cookie,將它扔給瀏覽器就可以把原來的cookie覆蓋了。
Cookie cookie = new Cookie("username","joker");// 新建Cookie cookie.setMaxAge(24*60*60); // 設置生命週期 response.addCookie(cookie); // 執行添加後就從response裏覆蓋修改了
2. 通過setValue()方法,修改cookie的值。
cookie.setValue("xxxxxxx");//修改cookie 的值 response.addCookie(cookie);//發送給瀏覽器
注意:修改、刪除Cookie時,新建的Cookie除value、maxAge之外的所有屬性,例如name、path、domain等,都要與原Cookie完全一樣。否則,瀏覽器將視爲兩個不同的Cookie而不會覆蓋之前的Cookie,從而導致修改、刪除失敗。
得到cookie簡單完整示例
@WebServlet("/RegisterServlet") public class register extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String username = request.getParameter("name"); //拿到傳過來的用戶名 Cookie cookie = new Cookie("uname",username); //創建一個cookie response.addCookie(cookie);//還回瀏覽器 //顯示到頁面上 response.getWriter().println("歡迎您"+username); response.getWriter().println("<hr/>"); response.getWriter().println("<a href='/TestCookie/ListServlet'>親愛的,您有多少封郵件未讀</a>"); } }
@WebServlet("/ListServlet") public class ListServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); Cookie[] cookies = request.getCookies(); //拿到傳過來的用戶名,得到cookie。 String uname = null; //先判斷有沒有cookie if(cookies!=null) { //遍歷所有的cookie for (Cookie cookie : cookies) { String cookieName =cookie.getName();//得到cookie的名稱 if("uname".equals(cookieName)) { uname = cookie.getValue(); //得到cookie的值 } } } response.getWriter().println("郵件已經沒有了"+uname); } }