-
會話技術概述
在浏覽器和伺服器建立連結之後,浏覽器和伺服器為了完成某一功能,浏覽器發送一次或多次請求,伺服器作出的一次或多次響應,在浏覽器關閉之前,所有的請求和響應就構成了一次會話。
-
HTTP協定特點:
HTTP無狀态協定:目前請求和上一次請求之間沒有任何的聯系。
-
使用會話技術的原因:
a. 為了能夠在多次請求響應之間共享資料,所有提出會話技術。
-
會話技術–cookie
a. cookie的實作原理
伺服器會在第一次響應的時候,通過set-cookie響應頭,将需要使用的資料發送到浏覽器,浏覽器會自動将其作為cookie儲存。在下一次請求時,會自動攜帶一個cookie請求頭,其中包含的内容就是浏覽器中的cookie資訊。
b. cookie特點:
cookie技術是一門浏覽器端的技術,資料儲存在浏覽器端。儲存安全性要求較低的資料。而存儲時間較長的資料。
c. 案例:傳回上次通路頁面的時間:
i. 在第一響應中,set-cookie儲存的資料會到達浏覽器。并且保留在浏覽器中。
ii. 在下一次的請求中,使用cookie請求頭,擷取cookie,得到結果。
代碼實作:
package cn.tedu.cookie;
import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //cookie原理實作 public class CookieDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //亂碼解決 response.setContentType("text/html;charset=utf-8"); //傳回頁面上一次的通路時間 Date date = new Date(); String time = date.toLocaleString();//擷取目前時間 //1.設定set-cookie響應頭 response.setHeader("set-cookie", "time="+time); //2.擷取請求頭cookie String cookie = request.getHeader("cookie"); //3.列印結果 if(cookie == null){//初次請求沒有cookie請求頭,是以cookie請求頭為null response.getWriter().write("您是初次通路本頁面"); }else{ response.getWriter().write("上次通路頁面的時間為:"+cookie); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
Cookie類
Sun公司提供了一個Cookie類,可以通過建立對象的方式,來建立cookie。
a. 建立cookie
Cookie cookie = new Cookie(String name,String value);
b. 設定cookie的生命時長
cookie的生命時長可以設定也可以不設定。如果不設定則目前cookie的生命時長,則cookie為一個會話級别的cookie,關閉浏覽器目前cookie就會銷毀。如果設定生命時長,則達到對應時間之後,會有浏覽器自動銷毀。
cookie.setMaxAge(秒);
c. 設定有效路徑
如果不設定有效路徑,則目前cookie的有效路徑為資源名稱部分,在這一部分中可以共享cookie。如果設定有效路徑,且為整個web應用,那麼在整個web應用的虛拟路徑級别之下都可以擷取到目前cookie
cookie.setPath(request.getContextPath()+"/");
d. 發送cookie
response.addCookie(Cookie)
e. 擷取cookie
request.getCookies(); —Cookie[]
f. 删除cookie
發送一個與要删除的cookie完全相同的cookie,并且設定它的生命時長為0,則這個cookie就可以被銷毀。完全相同的cookie,需要保證name+path+domain三者完成一緻。
g. 擷取cookie的名字
cookie.getName()
h. 擷取cookie的值
cookie.getValue()
i. 案例:通過cookie實作,頁面上次通路時間:
package cn.tedu.cookie;
import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //Cookie類實作傳回上次通路頁面的時間 public class CookieDemo2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //亂碼處理 response.setContentType("text/html;charset=utf-8"); Date date = new Date(); String time = date.toLocaleString(); //1.建立cookie Cookie cookie = new Cookie("time",time); //2.發送cookie--通過response對象發送 response.addCookie(cookie); //3.擷取cookie Cookie[] cs = request.getCookies(); //周遊數組 Cookie timeC = null; if(cs !=null){//初次通路頁面時,沒有任何cookie,是以會産生空指針異常,應該排除這種情況 for(Cookie c:cs){ if("time".equals(c.getName())){//從數組中擷取名稱為time的cookie timeC = c;//目前cookie對象範圍過小,無法在外側代碼操作,可以指派給更大範圍的變量去使用。 } } } //4.列印結果 if(timeC == null){ response.getWriter().write("您是初次通路本頁面"); }else{ response.getWriter().write("上次通路頁面的時間為:"+timeC.getValue()); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
EasyMall功能實作—記住使用者名
a. 導入login.jsp頁面
i. 從課前資料中複制login頁面内容。
ii. 将html頁面修改為jsp頁面
b. 修改_head.jsp
登入
c. 建立LoginServlet.java
package com.easymall.servlet;
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //登入Servlet public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.亂碼處理 request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //1.擷取參數 String username = request.getParameter("username"); String password = request.getParameter("password"); //擷取是否記住使用者名選項 String remname = request.getParameter("remname");//"true" null //2.記住使用者名--cookie //remname為"true"則需要記住使用者名,反之為null不需要記住使用者名。 if("true".equals(remname)){ Cookie cookie = new Cookie("remname",URLEncoder.encode(username, "utf-8")); cookie.setMaxAge(60*60*24*30);//30天記住使用者名 cookie.setPath(request.getContextPath()+"/"); response.addCookie(cookie); }else{ Cookie cookie = new Cookie("remname", ""); cookie.setMaxAge(0); cookie.setPath(request.getContextPath()+"/"); response.addCookie(cookie); } //3.儲存使用者登入狀态---session //4.跳轉回首頁 // response.sendRedirect("http://www.easymall.com"); response.sendRedirect(request.getContextPath()+"/"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
d. 修改login.jsp:添加如下代碼
<%
//擷取cookie中的remname 讀取其中的使用者名
Cookie[] cs = request.getCookies();
Cookie remnameC = null;
//初次擷取cookie數組為null
if(cs !=null){
for(Cookie c:cs){//周遊cookie數組,尋找remname這個cookie
if(“remname”.equals(c.getName())){
remnameC = c;
}
}
}
String username="";
if(remnameC !=null){
username = URLDecoder.decode(remnameC.getValue(), “utf-8”);
} %> <td><input type="text" name="username" value="<%=username%>"/></td> <input type="checkbox" name="remname" value="true" <%="".equals(username)?"":"checked='checked'" %> />記住使用者名
-
session概述
在浏覽器端儲存資料,資料可以被檢視、擷取,資料安全性較低。重要的資料應該存放在不容易擷取到的位置。伺服器是一個良好的選擇。資料通過伺服器共享,這門技術就是session會話技術。
-
Session工作原理
每一個浏覽器在通路伺服器時,都會建立各自對應的session對象來儲存資料。互相之間不會影響,是因為在session對象身上會包含一個sessionid,可以通過這個id來區分每一個浏覽器對應的session。
a. session工作原理:
本質是通過一個名稱為JSESSIONID的cookie來進行工作的。這個cookie會儲存在浏覽器中使用。
b. session的特點:
session是一門伺服器的技術,将資料儲存的伺服器端。儲存安全性要求較高的資料。且存儲時間較短的資料。
c. 建立session對象
request.getSession();//如果伺服器中有session對象,則取出使用,如果沒有session對象則建立一個新的session對象使用。
request.getSession(true);//如果伺服器中有session對象,則取出使用,如果沒有session對象則建立一個新的session對象使用。
request.getSession(false);//如果伺服器中沒有session對象,則傳回null,如果有session對想則取出使用。(判斷session是否存在時使用)
-
作為域對象使用
域對象:如果一個對象身上有一個可以被看見的範圍,在這個範圍内利用對象身上的map實作資料的共享,這個對象就可以稱之為域對象。
a. 操作api:
setAttribute(String name,Object obj) 設定域屬性
getAttribute(String name) 擷取域屬性
removeAttribute(String name ) 删除域屬性
getAttributeNames() 擷取所有的域屬性名稱
b. 生命周期:
request.getSession()方法調用的時候session對象産生。
i. 意外身亡:在伺服器意外關閉的情況下,session對象會被銷毀。在伺服器正常關閉的情況下,如果session對象未被釋放,則其中的内容會序列化到磁盤上,這個過程,稱之為鈍化。當伺服器再次啟動的時候,會重新讀取磁盤上這個檔案,這個過程稱之為活化。
ii. 自殺:主動session.invalidate()方法會立刻釋放目前session對象。
iii. 逾時死亡:在[tomcat]/conf/web.xml中有session預設的最大生命時長配置标簽,預設值為30分鐘。超過30分鐘,則目前session會被釋放。
c. 作用範圍:
整個會話範圍。
d. 主要功能:
在整個會話範圍内共享資料
e. 代碼實作:
i. SessionDemo1.java
package cn.tedu.session;
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; //session共享資料--作為域對象使用 public class SessionDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.擷取session對象 HttpSession session = request.getSession(); //2.作為域對象使用--設定域屬性 session.setAttribute("name", "曹洋"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } ii. SessionDemo2.java package cn.tedu.session; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class SessionDemo2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.擷取session對象 HttpSession session = request.getSession(true); //2.擷取域屬性 String name = (String) session.getAttribute("name"); System.out.println("name:"+name); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
案例:購物車
兩個Servlet:buyServlet/PayServlet
一個jsp:sale.jsp — 挑選商品 點選商品名稱加入購物車。點選付款按鈕為商品結賬。
index.jsp頁面
<%@ page language=“java” import=“java.util.*” pageEncoding=“utf-8” session=“false”%>
</head> <body> <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=滑鼠" target="_blank" rel="external nofollow" >滑鼠</a><br> <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=鍵盤" target="_blank" rel="external nofollow" >鍵盤</a><br> <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=月餅" target="_blank" rel="external nofollow" >月餅</a><br> <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=手機" target="_blank" rel="external nofollow" >手機</a><br> <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=拖鞋" target="_blank" rel="external nofollow" >拖鞋</a><br> <a href="http://localhost/day12-cookiesession/servlet/PayServlet" target="_blank" rel="external nofollow" >付款</a><br> </body> </html> buyServlet.java package cn.tedu.session; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; //購物車Servlet public class BuyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.請求亂碼 String prod = request.getParameter("prod"); prod = new String(prod.getBytes("iso8859-1"),"utf-8"); //2.響應亂碼處理 response.setContentType("text/html;charset=utf-8"); //将商品放入購物車 //1.擷取session對象 HttpSession session = request.getSession(); //關閉浏覽器前後都要操作同一個session //---在浏覽器端保留一個名稱為JSESSIONID的cookie,cookie值存儲session的id Cookie cookie = new Cookie("JSESSIONID",session.getId()); cookie.setMaxAge(60*60*24); cookie.setPath(request.getContextPath()+"/"); response.addCookie(cookie); //2.向session中添加域屬性 session.setAttribute("prod", prod); //3.在浏覽器中提示,商品加入購物車 response.getWriter().write("商品【"+prod+"】已經加入購物車"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } PayServlet.java package cn.tedu.session; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //支付Servlet public class PayServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //從session中取出商品 //1.響應亂碼處理 response.setContentType("text/html;charset=utf-8"); //2.判斷session是否存在--直接點選不會為任何商品付款 if(request.getSession(false) != null){ //3.如果存在,則取出域屬性 String prod = (String) request.getSession().getAttribute("prod"); //釋放session,清空購物車。 request.getSession(false).invalidate(); //頁面提示已為商品付款 response.getWriter().write("您以為商品【"+prod+"】付款¥10000"); }else{ //4.如果不存在則提示使用者尚未選擇商品 response.getWriter().write("您尚未選擇任何商品"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
EasyMall功能–登入
通過登入功能,儲存使用者的登入狀态。
request域~範圍太小
ServletContext域~範圍太大
session域–合适
a. 修改LoginServlet.java,添加如下代碼:
//3.儲存使用者登入狀态—session
//判斷使用者名域密碼是否比對
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(“select * from user where username =? and password=?”);
ps.setString(1, username);
ps.setString(2, password);
rs = ps.executeQuery();
if(rs.next()){//使用者名和密碼正确,完成登入
HttpSession session = request.getSession();
session.setAttribute(“username”, username);
}else{//傳回登入頁面作出提示
request.setAttribute(“msg”, “使用者名或密碼不正确”);
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCUtils.close(conn, ps, rs);
}
//4.跳轉回首頁 // response.sendRedirect("http://www.easymall.com"); response.sendRedirect(request.getContextPath()+"/");
b. _head.jsp頁面中添加如下内容:
<%
//判斷是否存在登入狀态
if(request.getSession(false) != null
&& request.getSession().getAttribute(“username”)!=null){
//第一個判斷是确認session對象是否存在,如果存在仍然不能确定是否包含username域屬性(登入狀态)
//第二個判斷是确認目前session對象中是否包含username屬性,如果包含才從中取出使用者名,在頁面中顯示
%>
歡迎<%=request.getSession().getAttribute(“username”) %>,回來 |
登出
<%
}else{
%>
登入 |
注冊
<%
}
%>
c. 在login.jsp中添加錯誤提示框
<%=request.getAttribute(“msg”)==null?"":request.getAttribute(“msg”) %>
-
登出功能
修改_head.jsp頁面
登出
建立LogOutServlet.java
package com.easymall.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//登出servlet
public class LogOutServlet extends HttpServlet {
}public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //登出使用者就是銷毀session if(request.getSession(false) !=null){ request.getSession().invalidate(); } //跳轉回首頁 response.sendRedirect(request.getContextPath()+"/"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
-
驗證碼實作
a. 在ValidateServlet中添加如下内容:
response.setDateHeader(“Expires”, -1);
response.setHeader(“Cache-Control”, “no-cache”);
VerifyCode vc = new VerifyCode();
//目前servlet隻有img标簽調用,是以将圖檔放入緩沖區,
//最終會在其調用的位置輸出在浏覽器中。
vc.drawImage(response.getOutputStream());
String code = vc.getCode();
//添加驗證碼到session域
request.getSession().setAttribute(“code”, code);
System.out.println(code);
System.out.println(“執行成功~!”);
b. 在registServlet中添加如下内容:
//6.驗證碼校驗
//TODO:session
//擷取域中驗證碼和使用者輸入的驗證碼,作比對
String code = (String) request.getSession().getAttribute(“code”);
if(!code.equalsIgnoreCase(valistr)){
request.setAttribute(“msg”, “驗證碼錯誤”);
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
-
Cookie特點:
cookie是将資料儲存在浏覽器端,是一門浏覽器端的技術。由于資料儲存在浏覽器端,是以可以被任意的檢視,安全性較低,但是可以長時間存儲資料。cookie善于存儲安全性要求較低,但是存儲時間較長的資料。
-
Session特點:
session是将資料儲存在伺服器端,是一門伺服器端的技術,資料儲存在伺服器端相對安全,但是伺服器無法保留大量session對象,是以不能夠長時間存儲資料。伺服器善于存儲安全性要求較高,但是存儲時間較短的資料。
-