JAVA EE-SESSION&COOKIE
應該相信,自己是生活的戰勝者。 —— 雨果
什麼是會話技術?
- 會話的概念:
日常生活來講.會話就是兩個人聊天. 聊天的前提,聊天雙方需要有記憶力. 在聊的過程中,都是基於之前聊的狀態,繼續往下聊.
我們javaweb中,瀏覽器和服務器也可以看作是雙方在聊天(請求,響應). 瀏覽器服務器雙方也需要有”記憶力”,保存之前的聊天狀態.服務器和瀏覽器纔可以完成會話. - 會話的範圍:
兩個從打招呼到兩人互相道別.是一次會話.
打開網站,完成我們想做的需求,到關閉瀏覽器.是一次會話.
Cookie: 讓瀏覽器能夠記錄信息.
Session:讓服務器端能夠記錄信息.
Cookie與Session的圖解
詳解Cookie技術
演示向瀏覽器發送cookie頭
//演示發送cookie(頭)到瀏覽器
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//明白原理的寫法:
//response.setHeader("set-Cookie", "name=tom");
//使用封裝好的代碼
//創建cookie對象 => 封裝鍵值對
Cookie cookie = new Cookie("name",URLEncoder.encode("湯姆","UTF-8"));
//將cookie添加到response中 => 添加響應頭
response.addCookie(cookie);
}
}
演示如何取出瀏覽器發出來的cookie
//演示取出瀏覽器發送過來的cookie
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 獲得瀏覽器發送的所有cookie
Cookie[] cookies = request.getCookies();
Cookie nameCookie = null;
//遍歷,找到我們要找的cookie
if(cookies!=null){
for(Cookie c : cookies){
if("name".equals(c.getName())){
//找到了
nameCookie = c;
}
}
}
if(nameCookie!=null){
System.out.println("瀏覽器發送的cookie==>" + nameCookie.getName()+":"+nameCookie.getValue());
System.out.println("瀏覽器發送的cookie==>" + nameCookie.getName()+":"+URLDecoder.decode(nameCookie.getValue(), "UTF-8"));
}else{
System.out.println("沒有找到namecookie");
}
}
}
令人十分不解的是,SUN公司還沒有對取出cookies進行優化,如果想取出特定鍵,必須遍歷後判斷。
但是我們可以通過自己封裝一個工具類來實現取出特定Cookie的目的。
public class CookieUtils {
public static Cookie getCookieByName(HttpServletRequest request,String name){
Cookie cookie = null;
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie c: cookies){
if(name.equals(c.getName())){
cookie = c;
}
}
}
return cookie;
}
}
設置cookie在何時後過期
public class CServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie c = new Cookie("name","jerry");
//設置cookie的有效時間
c.setMaxAge(60*60*24*7*2);//告訴瀏覽器保存2周
//c.setMaxAge(-1);// -1代表 在會話結束時刪除cookie(默認情況)
//c.setMaxAge(0);// 通常用於刪除已經存在的cookie.使用一個壽命爲0的cookie,覆蓋要刪除的cookie
response.addCookie(c);
}
}
設置Cookie的路徑
public class DServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie c = new Cookie("name","jack");
//設置Cookie的路徑
c.setPath("/day09-cookie/ABC");
response.addCookie(c);
}
}
保存訪問的歷史紀錄
public class EServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.獲得參數
String name = request.getParameter("name");
// 2.獲得Cookie
Cookie history = CookieUtils.getCookieByName(request, "history");
if(history!=null){
// //存在 => 修改cookie加上現在瀏覽器的品牌 => dell,hp,lenvo
if(!history.getValue().contains(name)){
history = new Cookie("history",history.getValue()+","+name);
}
}else{
// //不存在 => 創建cookie
history = new Cookie("history",name);
}
// 3.將cookie發送會瀏覽器
response.addCookie(history);
// 4.重定向到列表頁面
response.sendRedirect("/day09-cookie/history/list.jsp");
}
}
記住用戶名與密碼
public class FServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.獲得用戶名密碼
String name = request.getParameter("name");
// 2.校驗用戶名密碼
if(name==null || "".equals(name.trim())){
// //失敗=> 轉發到表單頁面,並提示錯誤
request.setAttribute("error", "請輸入用戶名!");
request.getRequestDispatcher("/remember/login.jsp").forward(request, response);
return;
}
// 3.創建cookie 添加要保存的用戶名,
Cookie c = new Cookie("remember", name);
// 4.查看記住用戶名是否被選中
String remember = request.getParameter("remember");
if("yes".equals(remember)){
// 選中 => 設置保存時間爲2周
c.setMaxAge(60*60*24*7*2);
}else{
// //沒選中=>設置保存事件爲0
c.setMaxAge(0);
}
// 5.添加到響應中
response.addCookie(c);
// 6.重定向到成功頁面
response.sendRedirect("/day09-cookie/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Session技術詳解
如何獲取Session對象
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//參數類型是boolean型
//true=> 無論如何都要獲得session
//false => 如果沒有sessionID ,不會獲得session
//request.getSession(true);
HttpSession session = request.getSession();//相當於上面的方法 填寫true
//session 的操作
// session.setAttribute(arg0, arg1)
// session.getAttribute(arg0)
// session.getAttributeNames()
// session.removeAttribute(arg0)
//session中可以存放登錄狀態
}
}
關於session對象的一些操作
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
System.out.println("session.isNew()"+session.isNew());// 判斷session是否 是新的.
System.out.println("session.getCreationTime()"+new Date(session.getCreationTime()));//獲得session的創建時間
System.out.println("session.getId()"+session.getId());//獲得session的id
System.out.println("session.getLastAccessedTime()"+new Date(session.getLastAccessedTime()));//獲得最後一次的訪問時間
System.out.println("session.getMaxInactiveInterval()"+session.getMaxInactiveInterval());// 獲得session的最大有效時間
//session.setMaxInactiveInterval(60);//設置session的最大有效時間爲60秒
session.invalidate();//*** 立即讓session銷燬.
}
}
Session的一些細節問題
Session的細節
1.Session的有效時間
默認:
30分鐘
手動指定:
* tomcat/conf/web.xml => <Session-timeout>
* 項目/WEB-INF/web.xml => <Session-timeout>
* 代碼: session.setMaxInactiveInterval(); 每次調用隻影響被調用的session對象
2.Session的作用範圍
一個會話期間
會話結束:
1.瀏覽器關閉
2.Session的過期
3.手動調用銷燬Session的方法
3.Session中的其他API
Session.invalidate() => 立即銷燬Session對象
利用Session與Cookie技術完成兩個實例的製作
購物車
先構建左側的購物車區域
</head>
<body>
<h1>商品列表</h1>
<table border="1" >
<tr>
<td>
<img src="/day09-cart/img/pic (1).jpg" width="300" height="200" /><br>
肥皂<br>
<a href="/day09-cart/AServlet?name=0" >點擊加入購物車</a>
</td>
<td>
<img src="/day09-cart/img/pic (2).jpg" width="300" height="200" /><br>
蠟燭<br>
<a href="/day09-cart/AServlet?name=1" >點擊加入購物車</a>
</td>
</tr>
<tr>
<td>
<img src="/day09-cart/img/pic (3).jpg" width="300" height="200" /><br>
被罩<br>
<a href="/day09-cart/AServlet?name=2" >點擊加入購物車</a>
</td>
<td>
<img src="/day09-cart/img/pic (4).jpg" width="300" height="200" /><br>
枕頭<br>
<a href="/day09-cart/AServlet?name=3" >點擊加入購物車</a>
</td>
</tr>
</table>
<a href="/day09-cart/cart.jsp" >查看購物車</a>
</body>
</html>
Servlet的業務邏輯代碼
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0 準備數組,與頁面商品對應
String[] products = {"肥皂","蠟燭","被罩","枕頭"};
// 1. 獲得當前請求要添加的商品
String indexStr = request.getParameter("name");// 0 ~ 3
String productName = products[Integer.parseInt(indexStr)];
// 2.從Session中取出存放購物車的map
Map<String,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");
if(cart==null){
// //取不到=>初始化map,
cart = new LinkedHashMap<String, Integer>();
//並放入session
request.getSession().setAttribute("cart", cart);
}
// 3.使用當前要添加的商品從map中取值
Integer count = cart.put(productName, 1);
if(count!=null){
cart.put(productName, count+1);
}
// //取不到=> 放入map,設置數量爲1
// //取得到=> 將數量+1放回去
// 4.重定向回商品列表頁面
response.sendRedirect("/day09-cart/list.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
用於顯示輸出的JSP
** </head>
<body>
<h1>購物車</h1>
<table border="1">
<tr>
<th>商品名稱</th>
<th>商品數量</th>
</tr>
<%
Map<String,Integer> cart = (Map<String,Integer>)session.getAttribute("cart");
if(cart!=null && cart.size()>0){
for(Entry<String,Integer> en : cart.entrySet()){
%>
<tr>
<td><%=en.getKey() %></td>
<td><%=en.getValue() %></td>
</tr>
<% }
}
%>
</table>
</body>
</html>**
驗證碼
生成驗證碼並且發送給瀏覽器的代碼邏輯
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0設置正文類型
response.setContentType("image/jpeg");
//1 生成驗證碼
ValidateCode code = new ValidateCode(150, 70, 4, 2);
//2 將正確答案放入Session
String str = code.getCode();
request.getSession().setAttribute("code", str);
System.out.println(str);
//3 將圖片流發送給瀏覽器
code.write(response.getOutputStream());
}
}
獲取並且判斷
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 獲得用戶填寫的驗證碼
String code1 = request.getParameter("code");
//2 獲得Session中正確的
String code2 = (String) request.getSession().getAttribute("code");
//3 比對
if(code1!=null && code1.equalsIgnoreCase(code2)){
//成功=> 登錄成功 => 重定向到登錄頁面
response.sendRedirect("/day09-checkcode/index.jsp");
}else{
//失敗=> 轉發到登錄頁面並提示
request.setAttribute("error", "請輸入正確的驗證碼");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
最終顯示的JSP代碼
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
function fun1(){ // 改變img標籤的src屬性值
//1 獲得img標籤對象
var img = document.getElementById("one");
//2 改變src屬性
img.src = "/day09-checkcode/AServlet?date="+new Date();
}
</script>
</head>
<body>
<form action="/day09-checkcode/BServlet" >
用戶名:<input type="text" name="name" /> <br>
密碼:<input type="text" name="password" /><br>
驗證碼:<input type="text" name="code" size="4" /><img id="one" src="/day09-checkcode/AServlet" >
<a href="javaScript:void(0)" onclick="fun1();" >看不清,換一張</a>
<font color="red" >${requestScope.error}</font>
<br>
<input type="submit" value="登錄" />
</form>
</body>
</html>