什麼是會話?javascript
會話能夠簡單理解爲:用戶開一個瀏覽器,點擊多個超連接,訪問服務器多個web資源,而後關閉瀏覽器,整個過程稱之爲一個會話。html
保存會話數據的兩種技術:Cookie和HttpSessionhtml5
Cookie:java
Cookie是客戶端技術,程序把每一個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶着各自的數據去。這樣,web資源處理的就是用戶各自的數據了。ios
1.Cookie入門案例(上次訪問時間)web
package cn.lsl.cookie; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; 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; public class LastVisit extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setDateHeader("Expires", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setContentType("text/html;charset=utf-8"); // 若是用戶第一次訪問 --- 判斷請求中有沒有cookie信息 Cookie[] cookies = request.getCookies(); if (cookies == null) { // 第一次訪問,沒有cookie,將當前時間以cookie寫回客戶端 long now = System.currentTimeMillis(); // 向客戶端寫cookie Cookie cookie = new Cookie("last", now + ""); cookie.setPath("/Cookie"); // 設置cookie有效時間 cookie.setMaxAge(60 * 60 * 24 * 2); // 寫cookie回到客戶端 response.addCookie(cookie); response.getWriter().println("歡迎你第一次訪問本網站!"); } else { // cookie存在 for (Cookie cookie : cookies) { if (cookie.getName().equals("last")) { long lasttime = Long.parseLong(cookie.getValue()); // 顯示給用戶 Date date = new Date(lasttime); DateFormat dateFormat = new SimpleDateFormat( "yyyy年MM月dd日 HH時mm分ss秒"); response.getWriter().println( "上次訪問時間:" + dateFormat.format(date)); } } // 更新最後訪問時間 long now = System.currentTimeMillis(); Cookie cookie = new Cookie("last", now + ""); cookie.setPath("/Cookie"); cookie.setMaxAge(60 * 60 * 24 * 2); response.addCookie(cookie); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
解析:數據庫
1)經過服務器向客戶端cookie瀏覽器
Cookie cookie = new Cookie(name,value);緩存
response.addCookie(cookie);安全
* 在HTTP協議響應頭信息中 Set-Cookie: last=1339556457609
2)當客戶端存在cookie以後,之後每次請求自動攜帶HTTP協議請求頭信息
Cookie: last=1339556456859
服務端得到須要cookie數據
Cookie[] cookie = request.getCookie();
遍歷cookie獲取須要信息
for(Cookie cookie : cookie){
if(cookie.getName().equals("last")){
}
}
2.會話cookie,持久cookie?
1)cookie信息默認狀況保存在瀏覽器內存中 --- 會話cookie
會話cookie會在關閉瀏覽器時清除
2)持久cookie,cookie數據保存客戶端硬盤上
經過setMaxAge設置Cookie爲持久Cookie
3.訪問cookie有效路徑
默認狀況下,生成cookie時,產生默認有效訪問路徑 (默認生成cookie程序路徑)
http://localhost:8080/Cookie/lastvisit --- 生成cookie --- path 默認值: /Cookie
http://localhost:8080/Cookie/servlet/path ---- 生成cookie ---- path 默認值:/Cookie/servlet
第二次訪問程序攜帶cookie信息,若是訪問路徑與path不一致,不會攜帶cookie 信息
* 之後程序開發,儘可能設置path ---- setPath方法
4.第一方cookie 和 第三方cookie
經過setDomain 設置cookie 有效域名
訪問google時,生成cookie過程當中 cookie.setDomain(".baidu.com") ---- 生成百度cookie ------ 第三方cookie
* 第三方cookie 屬於不安全 ----- 通常瀏覽器不接受第三方cookie
訪問google時,生成cookie,cookie.setDomain(.google.con) ---- 生成google的cookie ------ 第一方cookie
5.刪除cookie
原理:設置cookie MaxAge爲0
*刪除cookie時,必須設置path與cookie的path一致
eg:
package cn.lsl.cookie; 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; public class DeleteCookie extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("last",""); cookie.setMaxAge(0); cookie.setPath("/Cookie"); response.addCookie(cookie); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
6.顯示上次瀏覽的商品
Book.java(實體類)
package cn.lsl.domain; public class Book { private String id; private String name; private String author; private Double price; private String description; public Book(){} public Book(String id, String name, String author, Double price, String description) { super(); this.id = id; this.name = name; this.author = author; this.price = price; this.description = description; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "Book [author=" + author + ", description=" + description + ", id=" + id + ", name=" + name + ", price=" + price + "]"; } }
BookDB.java(模擬數據庫)
package cn.lsl.db; import java.util.LinkedHashMap; import java.util.Map; import cn.lsl.domain.Book; public class BookDB { private static Map<String, Book> books = new LinkedHashMap<String, Book>(); static{ books.put("1", new Book("1", "Java", "張三", 35.00, "Java入門")); books.put("2", new Book("2", "JavaEE", "李四", 45.00, "JavaEE入門")); books.put("3", new Book("3", "Android", "王五", 45.00, "Android入門")); books.put("4", new Book("4", "ios", "小舒", 55.00, "ios入門")); books.put("5", new Book("5", "html5", "小五", 35.00, "html5入門")); } //根據id查詢書本 public static Book findBookById(String bookId){ return books.get(bookId); } //查詢全部的書本 public static Map<String, Book> findAllBooks(){ return books; } }
ShowBookServlet.java(顯示全部書籍)
package cn.lsl.cookie; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; 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 cn.lsl.db.BookDB; import cn.lsl.domain.Book; public class ShowBookServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.write("<h1>本站有如下書籍</h1>"); Map<String, Book> books = BookDB.findAllBooks(); for (Map.Entry<String, Book> me : books.entrySet()) { out.write(me.getValue().getName()+" <a href='/Cookie/servlet/ShowBookDetailServlet?id="+me.getKey()+"'>查看詳情</a><br/>"); } //顯示用戶最近的瀏覽記錄 out.write("<hr/>"); out.write("<a href='/Cookie/servlet/CleanHistoryServlet'>清空瀏覽記錄</a>"); out.write("<h3>您最近的商品瀏覽記錄</h3>"); Cookie[] cs = request.getCookies(); for(int i=0; cs!=null&&i<cs.length; i++){ if("bookHistory".equals(cs[i].getName())){ String value = cs[i].getValue(); String ids[] = value.split("\\-"); for (String id : ids) { out.write(BookDB.findBookById(id).getName()+"<br/>"); } break; } } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
ShowBookDetailServlet.java(查看詳細信息)
package cn.lsl.cookie; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.LinkedList; 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 cn.lsl.db.BookDB; import cn.lsl.domain.Book; public class ShowBookDetailServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String id = request.getParameter("id"); Book book = BookDB.findBookById(id); out.write(book.toString()); //向客戶端寫Cookie String ids = makeIds(request, id); Cookie c = new Cookie("bookHistory",ids); c.setMaxAge(Integer.MAX_VALUE); c.setPath(request.getContextPath()); response.addCookie(c); } private String makeIds(HttpServletRequest request, String id) { // TODO Auto-generated method stub //a Cookie cs[] = request.getCookies(); if(cs == null) return id; //b Cookie cookie = null; for (Cookie c : cs) { if("bookHistory".equals(c.getName())){ cookie = c; break; } } if(cookie == null) return id; //cdefg String ids[] = cookie.getValue().split("\\-"); LinkedList<String> list = new LinkedList<String>(Arrays.asList(ids)); if(list.size()<3){ if(list.contains(id)){ list.remove(id); } list.addFirst(id); }else{ if(list.contains(id)){ list.remove(id); }else{ list.removeLast(); } list.addFirst(id); } StringBuffer sb = new StringBuffer(); for (int i = 0; i < list.size(); i++) { if(i>0) sb.append("-"); sb.append(list.get(i)); } return sb.toString(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
CleanHistoryServlet.java
package cn.lsl.cookie; 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; public class CleanHistoryServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("bookHistory",""); cookie.setMaxAge(0); cookie.setPath(request.getContextPath()); response.addCookie(cookie); response.sendRedirect("/Cookie/servlet/ShowBookServlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
7.Cookie細節
1)一個Cookie只能標識一種信息,它至少含有一個標識該信息的名稱和設置值。
2)一個WEB站點能夠給一個WEB瀏覽器發送多個Cookie,一個WEB瀏覽器能夠存儲多個WEB站點提供的Cookie。
3)瀏覽器通常只容許存放300個Cookie,每一個站點最多存放20個Cookie,,每一個Cookie的大小限制爲4KB.
4)若是建立了一個Cookie,並將他發送到瀏覽器,默認狀況下它是一個會話級別的cookie(即存儲在瀏覽器的內存中),用戶推出瀏覽器以後即被刪除。若但願瀏覽器將還cookie存儲在磁盤上,則須要使用maxAge,並給出一個以秒爲單位的時間。將最大時效設爲0則是命令瀏覽器刪除該cookie。
4)刪除cookie時,path必須一致,不然不會刪除。
HttpSession
Session是服務器端技術,利用這個技術,服務器在運行時能夠爲每個用戶的瀏覽器建立一個其獨享的HttpSession對象,因爲session爲用戶瀏覽器獨享,因此用戶在訪問服務器的web資源時,能夠把各自的數據放在各自的session中,當用戶再去訪問服務器中的其餘web資源時,其餘web資源再從個各自用戶的session中取出數據爲用戶服務。
Session和Cookie的主要區別:
1)Cookie是把用戶的數據寫給用戶瀏覽器的。Session技術把用戶的數據寫到用戶獨佔的session中,
2)Session對象由服務器建立,開發人員能夠調用request對象的getSession方法獲得session對象。
Session快速入門案例(實現數據共享)
SessionDemo1.java
package cn.lsl.session; import java.io.IOException; import java.io.PrintWriter; 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 SessionDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); HttpSession session = request.getSession(); System.out.println(session.getId()); session.setAttribute("username", name); PrintWriter out = response.getWriter(); out.write("put done!"); out.write("<a href='/Session/servlet/SessionDemo2'>link</a>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
SessionDemo2.java
package cn.lsl.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 { HttpSession session = request.getSession(); String value = (String)session.getAttribute("username"); response.getWriter().write(value); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
注:
HttpServletRequest.getSession():根據特殊Cookie(JSESSIONID=HttpSession對象的id,由服務器生成,惟一的)的取值,在服務器的內存中根據id查找這個HttpSession對象,找到了,取出來繼續服務;沒有找到,建立一個新的HttpSession對象。
HttpServletRequest.getSession(boolean b):若是b爲true,與上面方法功能徹底一致。若是爲false,只查詢。
案例:用戶的一次性登錄和隨機驗證碼驗證
User.java(實體類)
package cn.lsl.domain; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
ImageServlet.java(隨機驗證碼)
package cn.lsl.code; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ImageServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 通知瀏覽器不要緩存 response.setHeader("Expires", "-1"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); int width = 120; int height = 25; // 建立一副內存圖像BufferedImage BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 獲得屬於該圖片的畫筆:Graphics(); Graphics g = image.getGraphics(); // 畫邊框 g.setColor(Color.BLUE); g.drawRect(0, 0, width, height); // 填充背景色 g.setColor(Color.YELLOW); g.fillRect(1, 1, width - 2, height - 2); // 畫干擾線 g.setColor(Color.GRAY); Random r = new Random(); for (int i = 0; i < 10; i++) g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r .nextInt(height)); // 隨機數字 g.setColor(Color.RED); g.setFont(new Font("宋體", Font.BOLD | Font.ITALIC, 20)); int x = 23; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 4; i++) { String code = r.nextInt(10) + ""; sb.append(code); g.drawString(code , x, 20); x = x + 20; } //把驗證碼放到HttpSession中 request.getSession().setAttribute("code", sb.toString()); // 輸出到瀏覽器的頁面上:ImageIO ImageIO.write(image, "jpg", response.getOutputStream()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
login.html(登錄頁)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>login.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <form action="/Session/servlet/LoginServlet" method="post"> 用戶名:<input type="text" name="username" /><br/> 密碼:<input type="password" name="password" /><br/> 驗證碼:<input type="text" name="code" /><img src="/Session/servlet/ImageServlet"><br/> <input type="submit" value="登錄" /> </form> </body> </html>
IndexServlet.java(主頁)
package cn.lsl.code; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import cn.lsl.domain.User; public class IndexServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(); User user = (User)session.getAttribute("user"); if(user == null){ out.write("<a href='/Session/login.html'>登錄</a>"); }else{ out.write("歡迎您:"+user.getUsername()+" <a href='/Session/servlet/LogoutServlet'>註銷</a>"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
LoginServlet.java(登錄)
package cn.lsl.code; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.lsl.domain.User; public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //驗證用戶名和密碼是否正確 String username = request.getParameter("username"); String password = request.getParameter("password"); String code = request.getParameter("code"); String sessionCode = (String)request.getSession().getAttribute("code"); if(!code.equalsIgnoreCase(sessionCode)){ out.write("錯誤的驗證碼<a href='/Session/login.html'>返回</a>"); return; } StringBuffer sb = new StringBuffer(password); password = sb.reverse().toString(); if(username.equals(password)){ User user = new User(); user.setUsername(username); user.setPassword(password); request.getSession().setAttribute("user", user); out.write("登錄成功。2秒後自動轉回主頁"); }else{ out.write("錯誤的用戶名或密碼。2秒後自動轉回主頁"); } response.setHeader("Refresh", "2;URL=/Session/servlet/IndexServlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
LogoutServlet.java(註銷)
package cn.lsl.code; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LogoutServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); request.getSession().removeAttribute("user"); out.write("註銷成功!2秒後將自動跳轉向主頁"); response.setHeader("Refresh", "2;URL=/Session/servlet/IndexServlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
簡單的購物車案例
Book.java(實體類)
package cn.lsl.domain; import java.io.Serializable; public class Book implements Serializable { private String id; private String name; private String author; private Double price; private String description; public Book(){} public Book(String id, String name, String author, Double price, String description) { super(); this.id = id; this.name = name; this.author = author; this.price = price; this.description = description; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "Book [author=" + author + ", description=" + description + ", id=" + id + ", name=" + name + ", price=" + price + "]"; } }
BookDB.java(模擬數據庫)
package cn.lsl.db; import java.util.LinkedHashMap; import java.util.Map; import cn.lsl.domain.Book; public class BookDB { private static Map<String, Book> books = new LinkedHashMap<String, Book>(); static{ books.put("1", new Book("1", "Java", "張三", 35.00, "Java入門")); books.put("2", new Book("2", "JavaEE", "李四", 45.00, "JavaEE入門")); books.put("3", new Book("3", "Android", "王五", 45.00, "Android入門")); books.put("4", new Book("4", "ios", "小舒", 55.00, "ios入門")); books.put("5", new Book("5", "html5", "小五", 35.00, "html5入門")); } //根據id查詢書本 public static Book findBookById(String bookId){ return books.get(bookId); } //查詢全部的書本 public static Map<String, Book> findAllBooks(){ return books; } }
ShowAllBooksServlet.java(顯示全部書籍)
package cn.lsl.cart; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.lsl.db.BookDB; import cn.lsl.domain.Book; public class ShowAllBooksServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); request.getSession(); //顯示全部商品 out.write("<h1>本站有如下商品</h1>"); Map<String,Book> books = BookDB.findAllBooks(); for (Map.Entry<String, Book> me : books.entrySet()) { String url = "/Session/servlet/BuyServlet?id="+me.getKey(); url = response.encodeURL(url); out.write(me.getValue().getName()+" <a href='"+url+"'>購買</a><br/>"); } //提供出查看購物車的連接 String url = "/Session/servlet/ShowCartServlet"; url = response.encodeURL(url); out.write("<a href='"+url+"'>查看購物車</a>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
BuyServlet.java(加入購物車)
package cn.lsl.cart; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; 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; import cn.lsl.db.BookDB; import cn.lsl.domain.Book; public class BuyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String id = request.getParameter("id"); Book book = BookDB.findBookById(id); //先查看有無購物車,若是有,直接用,沒有就建立一個 HttpSession session = request.getSession(); List<Book> cart = (List<Book>) session.getAttribute("cart"); if(cart == null){ cart = new ArrayList<Book>(); session.setAttribute("cart", cart); } cart.add(book); out.write(book.getName()+"已經放入購物車<br/>"); String url = "/Session/servlet/ShowAllBooksServlet"; url = response.encodeURL(url); out.write("<a href='"+url+"'>繼續購物</a>"); //本身寫Cookie Cookie c = new Cookie("JSESSIONID",session.getId()); c.setPath(request.getContextPath()); c.setMaxAge(Integer.MAX_VALUE); response.addCookie(c); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
ShowCartServlet.java(查看購物車)
package cn.lsl.cart; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import cn.lsl.domain.Book; public class ShowCartServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(false); if(session == null){ out.write("對不起!您還不曾購物"); }else{ List<Book> cart = (List<Book>) session.getAttribute("cart"); if(cart == null){ out.write("對不起!您還不曾購物"); }else{ out.write("您購買的商品以下:<br/>"); for (Book book : cart) { out.write(book.getName()+"<br/>"); } } } String url = "/Session/servlet/ShowAllBooksServlet"; url = response.encodeURL(url); out.write("<a href='"+url+"'>繼續購物</a>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
拓展:重寫url
url---->url;JSESSIONID=123:URL重寫.必須對網站中的全部URL地址都重寫。
HttpServletResponse.encodeURL(url):是一個智能方法。判斷用戶是否禁用了Cookie,沒有禁用,則不重寫;禁用了就重寫。
案例:防止表單重複提交
原理:表單頁面由servlet程序生成,servlet爲每次產生的表單頁面分配一個惟一的隨機標識號,並在FROM表單的一個隱藏字段中設置這個標識號,同時在當前用的session域中保存這個標識號。當用戶提交FROM表單時,負責處理表單提交的servlet獲得表單的標識號,並與session中存儲的標識號比較,若是相同則處理表單提交,處理完後清除當前用戶的Session域存儲的標識號。
在下列狀況下,服務器程序將拒絕用戶提交的表單請求:
1)存儲Session域中的表單標識號與表單提交的標識號不一樣
2)當前用戶的Session中不存在表單標識號
3)用戶提交的表單數據中沒有標識號字段
原理圖:
RegistUIServlet.java
package cn.lsl.session; import java.io.IOException; import java.io.PrintWriter; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegistUIServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //隨機生成一個令牌 String token = UUID.randomUUID().toString();//惟一的一段序列 //放入HttpSession中 request.getSession().setAttribute("token", token); out.write("<form id='f1' action='"+request.getContextPath()+"/servlet/RegistServlet' method='post'>"); out.write("姓名:<input type='text' name='name'/><br/>"); out.write("<input type='hidden' name='token' value='"+token+"'/>"); out.write("<input id='bt1' type='button' value='註冊' onclick='toSubmit()'/></form>"); out.write("<script type='text/javascript'>function toSubmit(){document.getElementById('f1').submit();document.getElementById('bt1').disabled=true;}</script>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
RegistServlet.java
package cn.lsl.session; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegistServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("UTF-8"); String name = request.getParameter("name"); //判斷用戶是否重複提交 String formToken = request.getParameter("token"); String sessionToken = (String)request.getSession().getAttribute("token"); if(formToken.equals(sessionToken)){ //正常提交 System.out.println("保存了:"+name); request.getSession().removeAttribute("token"); }else{ out.write("請不要重複提交"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
更改內存中HttpSession對象的超時時間
修改web.xml
<session-config> <session-timeout>1</session-timeout><!--天然整數,單位是分鐘--> </session-config>