在WEB開發中,服務器能夠爲每一個用戶瀏覽器建立一個會話對象(session對象),注意:一個瀏覽器獨佔一個session對象(默認狀況下)。所以,在須要保存用戶數據時,服務器程序能夠把用戶數據寫到用戶瀏覽器獨佔的session中,當用戶使用瀏覽器訪問其它程序時,其它程序能夠從用戶的session中取出該用戶的數據,爲用戶服務。html
1. Cookie是把用戶的數據寫給用戶的瀏覽器。java
2. Session技術把用戶的數據寫到用戶獨佔的session中。
web
3. cookie是客戶端技術數據庫
1). 數據保存在客戶端,這個信息能夠保存很長時間瀏覽器
2). 數據隨時有可能被清空,因此cookie保存的數據是不太靠譜的安全
3). 數據被保存在了客戶端,隨時有可能被人看走,若是將一些敏感信息好比用戶名密碼等信息存在cookie中,可能有安全問題服務器
4. session是服務器端技術cookie
1). 數據保存在服務區端,相對來講比較穩定和安全session
2). 佔用服務器內存,因此通常存活的時間不會太長,超過超時時間就會被銷燬.咱們要根據服務器的壓力和session 的使用狀況合理設置session的超時時間,既能保證session的存活時間夠用,同時不用的session能夠及時銷燬減小對服務器內存的佔用.dom
1. 做用範圍:當前會話範圍
2. 生命週期:
1) 當程序第一次調用到request.getSession()方法時說明客戶端明確的須要用到session此時建立出對應客戶端的Session對象.
2) 當session超過30分鐘(能夠在web.xml中配置<session-config>設置該時間值)沒有人使用則認爲session超時銷燬這個session.
3) 程序中明確的調用session.invalidate()方法能夠當即殺死session.
4) 當服務器被非正常關閉時,隨着虛擬機的死亡而死亡.
5) *若是服務器是正常關閉,還未超時的session會被以文件的形式保存在服務器的work目錄下,這個過程叫作session的鈍化.下次再正常啓動服務器時,鈍化着的session會被恢復到內存中,這個過程叫作session的活化.
3. 做用:在會話範圍內共享數據
1. 檢查請求中有沒有名字爲 jsessionid的cookie,若是有,則拿出值(值爲session 的惟一id)找到對應的session.
2. 若是沒有,則檢查請求的URL後有沒有以參數的名字爲jsessionid ,若是有則找到對應的Session。
3. 若是cookie中和url參數中都沒有找到,則認爲這個瀏覽器沒有對應的Session,建立一個Session而後再在響應中添加名字爲 jsessionid 的cookie,值就是這個Session 的id。
默認狀況下,JSESSIONID 的path爲當前web應用的名稱,而且沒有設置過MaxAge,是一個會話級別的cookie. 這意味着一旦關閉瀏覽器再新開瀏覽器時,因爲JSESSIONID丟失,會找不到以前的Session。另外同時打開多個IE瀏覽器也沒法共享同一session
所以咱們能夠手動的發送名字爲 jsessionid 的cookie,名字和path設置的和自動發送時同樣,可是設置一下MaxAge,使瀏覽器除了在內存中保存JSESSIONID信息之外還在臨時文件夾中以文件的形式保存,這樣即便重開瀏覽器仍然可使用以前的session。
/** * 設置session ,自定義jsessionid 的cookie。 * ① 防止瀏覽器關閉等狀況形成的session丟失 * ② 同時打開多個同種(IE)瀏覽器 ,共享session * * @param strName * @param strValue * @param hour * 有效小時數,若是此參數爲0,cookie在瀏覽器關閉的時候自動失效 * @return * @throws UnsupportedEncodingException */ public static void SetSesionCookie(HttpServletRequest request, HttpServletResponse response, String strName, String strValue, int hour) throws UnsupportedEncodingException { // String prod = request.getParameter(strName); // prod = new String(prod.getBytes("iso8859-1"), "utf-8"); HttpSession session = request.getSession(); // 自定義jsessionid 的cookie義 Cookie jc = new Cookie("JSESSIONID", session.getId()); jc.setPath(request.getContextPath()); jc.setMaxAge(hour); response.addCookie(jc); session.setAttribute(strName, strValue); }
若是瀏覽器禁用了Cookie,瀏覽器就沒有辦法JSESSIONID cookie,這樣就用不了Session了.
1). 咱們可使用URL重寫的機制,在全部的超連接後都以參數的形式拼接JSESSIONID信息,從而在點擊超連接時可使用URL參數的方式待會JSESSIONID,從而使用Session
2). 將URL進行重寫拼接上JSESSIONID的過程就叫作URL重寫
request.getSession() --在URL重寫以前必定要先建立出Session,纔有Session id,才能進行重寫
response.encodeURL()--- 通常的地址都用這個方法重寫
response.encodeRedirectURL() --- 若是地址是用來進行重定向的則使用這個方法
*url重寫的方法一旦發現瀏覽器帶回了任意cookie信息,則認爲客戶端沒有禁用cookie,就不會再進行重寫操做
<% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; request.getSession(); String url1 = path + "/servlet/BuyServlet?prod=電視機"; //encodeURL 方法,若是發現瀏覽器帶回了任意cookie信息,則認爲客戶端沒有禁用cookie,就不會再進行重寫操做,不然會重寫, //在url後面加jsessionid,改爲 path + "/servlet/BuyServlet;jessionid=ASDADKLADJFIOJQEWLADFAL?prod=電視機 url1 = response.encodeURL(url1); String url2 = path + "/servlet/BuyServlet?prod=冰箱"; url2 = response.encodeURL(url2); String url3 = path + "/servlet/PayServlet"; url3 = response.encodeURL(url3); %>
<a href="<%=url1%>">電視機</a> <br /> <a href="<%=url2%>">冰箱</a> <br /> <a href="<%=url3%>">結帳</a> <br />
1. 在頁面上生成一個隨機數的session,同時將值賦值隱藏控件,兩個值是相等的。
<% Random r = new Random(); int valinum = r.nextInt(); session.setAttribute("valinum",valinum+""); %> <form action="${pageContext.request.contextPath }/servlet/ResubServlet" method="POST" onsubmit="return canSub()"> 用戶名: <input type="text" name="username" /> <input type="hidden" name="valinum" value="<%=valinum %>" /> <input type="submit" value="註冊" /> </form>
2. 在後臺取出,隱藏控件中的值、session中的值,第一次提交後,移除session中的值,此時兩個值再也不相等了。
3. 若是是第二次提交,兩個值不相等,說明是重複提交。
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); String username = request.getParameter("username"); String hideVal = request.getParameter("valinum"); String sessionVal = (String) request.getSession().getAttribute( "valinum"); if (sessionVal != null && !"".equals(sessionVal) && hideVal.equals(sessionVal)) { request.getSession().removeAttribute("valinum"); System.out.println("向數據庫中註冊一次:" + username); } else { response.getWriter().write("from web:不要重複提交!!"); } }
/** * 設置session ,自定義jsessionid 的cookie。 * ① 防止瀏覽器關閉等狀況形成的session丟失 * ② 同時打開多個同種(IE)瀏覽器 ,共享session * * @param strName * @param strValue * @param hour * 有效小時數,若是此參數爲0,cookie在瀏覽器關閉的時候自動失效 * @return * @throws UnsupportedEncodingException */ public static void SetSesionCookie(HttpServletRequest request, HttpServletResponse response, String strName, String strValue, int hour) throws UnsupportedEncodingException { // String prod = request.getParameter(strName); // prod = new String(prod.getBytes("iso8859-1"), "utf-8"); HttpSession session = request.getSession(); // 自定義jsessionid 的cookie義 Cookie jc = new Cookie("JSESSIONID", session.getId()); jc.setPath(request.getContextPath()); jc.setMaxAge(hour); response.addCookie(jc); session.setAttribute(strName, strValue); } /** * 設置session * * @param strName * @param strValue * @param hour * 有效小時數,若是此參數爲0,cookie在瀏覽器關閉的時候自動失效 * @return * @throws UnsupportedEncodingException */ public static void SetSesion(HttpServletRequest request, String strName, String strValue) throws UnsupportedEncodingException { HttpSession session = request.getSession(); session.setAttribute(strName, strValue); } /** * 讀取session 若是爲空,返回null * * @param strName * @return * @throws UnsupportedEncodingException */ public static String GetSession(HttpServletRequest request, HttpServletResponse response, String strName) throws UnsupportedEncodingException { // 通知瀏覽器以UTF-8碼錶打開回送的數據 response.setContentType("text/html;charset=utf-8"); HttpSession session = request.getSession(); // String prod = new String(prod.getBytes("iso8859-1"), "utf-8"); String prod = (String) session.getAttribute(strName); return prod; } /** * 刪除指定session * * @param strName * @return */ public static void DelSession(HttpServletRequest request, String strName) { if (request.getSession(false) != null && request.getSession().getAttribute(strName) != null) { request.getSession().removeAttribute(strName); // request.getSession().invalidate(); } } /** * 刪除全部session * * @return */ public static void DelAllSession(HttpServletRequest request) { if (request.getSession(false) != null) { request.getSession(false).invalidate(); } }