Cookie和HttpSession的使用小案例
阿新 • • 發佈:2018-12-20
CookieAPI的使用
- 下面程式碼展示通過設定cookie存活時間來儲存使用者名稱
package servlet;
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 java.io.IOException;
import java.io.PrintWriter;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter ();
String userName ="";
String checked = "";
//得到客戶端儲存的Cookie資料
Cookie[] cookies = request.getCookies();
for (int i = 0;cookies!=null && i < cookies.length; i++) {
if("userName".equals(cookies[i].getName())){
userName = cookies[ i].getValue();//如果有cookie則自動填充
checked = "checked='checked'";//如果有cookie則自動勾選
}
}
out.write("<form action='"+request.getContextPath()+"/doLogin' method='post'>");
out.write("使用者名稱:<input type='text' name='userName' value='"+userName+"'/><br/>");
out.write("密碼:<input type='password' name='pwd'/><br/>");
out.write("<input type='checkbox' name='remember' "+checked+" />記住使用者名稱<br/>");
out.write("<input type='submit' value='登入'/><br/>");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 上面Servlet實現了登入介面,下面Servlet用來實現獲取表單資料、處理業務邏輯、分發轉向的功能
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
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 DoLoginServlet 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 pwd = request.getParameter("pwd");
String remember = request.getParameter("remember");
Cookie ck = new Cookie("userName", userName);//建立Cookie
ck.setPath("/");//設定Cookie的路徑為專案路徑
//處理業務邏輯
//分發轉向
if("tom".equals(userName)&&"123".equals(pwd)){
if(remember!=null){
ck.setMaxAge(Integer.MAX_VALUE);//設定Cookie的有效儲存時間
}else{
ck.setMaxAge(0);//設定時間為0表示立即刪除Cookie
}
response.addCookie(ck);//將Cookie寫回到客戶端,當時間設定為0時,執行刪除操作
out.write("登入成功!");
}else{
out.write("登入失敗!");
//設定2秒跳到重新登入
response.setHeader("refresh", "2;url="+request.getContextPath()+"/login");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 下面程式碼利用cookie實現儲存使用者最近三條瀏覽記錄的功能。
- 需要用到的類包括兩個Servlet、一個商品(書)類和一個工具類(用來模擬對資料庫的讀取操作)。
- 兩個Servlet分別用來展示所有書和每個書的詳細資訊。其中用來展示所有書的頁面包括了最近瀏覽的三條記錄。
- 經過分析發現新增cookie的功能應該在詳細資訊的Servlet中寫,因為只有點了某本書,才會將這本書新增到cookie中。而讀取cookie的功能則應該寫在展示所有書資訊的Servlet中。
package servlet;
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 entity.Book;
import util.DBUtil;
//該Servlet是用來展示所有書資訊和歷史瀏覽記錄的
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();
out.write("本網站有以下好書:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
//每一本書都連線到詳細資訊頁面,不過需要在跳轉連結中加上書的id
out.write("<a href='"+request.getContextPath()+"/showBookDetail?id="+book.getKey()+"' target='_blank'>"+book.getValue().getName()+"</a><br/>");
}
out.write("<hr/>您最近瀏覽過的書有:<br/>");
Cookie[] cookies = request.getCookies();//獲取cookie陣列
for (int i = 0;cookies!=null && i < cookies.length; i++) {
if("historyBookId".equals(cookies[i].getName())){//判斷是否有historyBookId的cookie
//獲取名為historyBookId的cookie值,也就是歷史瀏覽書本的id拼接的字串
String value = cookies[i].getValue();
String[] ids = value.split("-");
for (int j = 0; j < ids.length; j++) {
Book book = DBUtil.findBookById(ids[j]);//根據ID得到指定的書
out.print(book.getName()+"<br/>");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 上面是用來展示全部商品資訊的Servlet,下面是用來展示商品詳細資訊的Servlet
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.naming.LinkLoopException;
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 entity.Book;
import util.DBUtil;
public class ShowBookDetail extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//顯示圖書的詳細資訊
//獲得id。無論是post還是get方式提交都可以通過該方法來獲取值
String id = request.getParameter("id");
Book book = DBUtil.findBookById(id);
//out.write(book.toString());
out.print(book);
//把當前瀏覽過的書的id寫回到客戶端cookie
//organizeId方法能夠讀取原本cookie中有關歷史記錄的cookie值,然後將其修改後返回回來
String historyBookId = organizeId(id,request);
Cookie ck = new Cookie("historyBookId",historyBookId);
ck.setPath("/");
ck.setMaxAge(Integer.MAX_VALUE);//設定cookie的儲存時間
response.addCookie(ck);//寫回到客戶端cookie
}
/**
* 客戶端 點選的書ID 修改後的cookie值
* 沒有Cookie 1 historyBookId=1
* 有Cookie,但沒有historyBookId 1 historyBookId=1
* historyBookId=1 2 historyBookId=2-1
* historyBookId=1-2 2 historyBookId=2-1
* historyBookId=1-2-3 2 historyBookId=2-1-3
* historyBookId=1-2-3 4 historyBookId=4-1-2
*/
private String organizeId(String id, HttpServletRequest request) {
//得到客戶端的Cookie
Cookie[] cookies = request.getCookies();
if(cookies==null){
return id;
}
//查詢有沒有name叫做historyBookId的cookie
Cookie historyBook = null;
for (int i = 0; i < cookies.length; i++) {
if("historyBookId".equals(cookies[i].getName())){
historyBook = cookies[i];
}
}
//如果沒有historyBookId的cookie,則還返回id
if(historyBook==null){
return id;
}
//獲取名為historyBookId的cookie值,也就是歷史瀏覽書本的id拼接的字串
String value = historyBook.getValue();
String[] values = value.split("-");
LinkedList<String> list = new LinkedList<String>(Arrays.asList(values));
//歷史記錄中最多隻儲存3條記錄
if(list.size()<3){ // 1 2
if(list.contains(id)){
list.remove(id);//如果包含當前id的值,則刪除這個id
}
}else{
if(list.contains(id)){
list.remove(id);
}else{//說明有3本書的id了
list.removeLast();//把最後一個id刪除
}
}
list.addFirst(id);//最新書的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();//將StringBuffer型別轉為String型別
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 工具類
package servlet;
import java.util.HashMap;
import java.util.Map;
import entity.Book;
public class DBUtil {
private static Map<String, Book> books = new HashMap<String, Book>();
static{
books.put("1", new Book("1", "金瓶梅", 20, "王瑞鑫"));
books.put("2", new Book("2", "葵花寶典", 20, "楊成毅"));
books.put("3", new Book("3", "九陰真經", 30, "陳光"));
books.put("4", new Book("4", "玉女心經", 10, "陳志家"));
}
//得到所有書
public static Map<String, Book> findAllBooks(){
return books;
}
/**
* 根據id查詢指定的書
* @param id
* @return
*/
public static Book findBookById(String id){
return books.get(id);
}
}
HttpSession
- HttpSession也是一個域物件,它是介於ServletContext和ServletRequest中間的域物件。ServletRequest的範圍只限於同一個request,ServletContext的範圍是整個專案資源都可以進行設定和獲取物件。而HttpSession則是同一會話中的所有資源通向同一個HttpSession物件,可以設定和獲取物件。不同的會話對應著不同的HttpSession。
- HttpSession與Cookie的區別在於:
- Cookie是客戶端技術,只能存取字串
- HttpSession是伺服器端技術,可以存取物件
- 下面展示一個例子,通過HttpSession實現購物車功能,能夠區別不同使用者(購物車存在HttpSession當中)
- 包括三個Servlet(用於展示所有商品資訊,用於新增一本選中的書到購物車中,用於展示購物車中的內容)、兩個類(Book和DBUtil用來模擬資料庫,跟上面一個例子相同)
package servlet;
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 entity.Book;
import util.DBUtil;
//
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();
out.print("本網站有以下好書:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
//點選連結新增商品到購物車,關聯一個Servlet
out.print("<a href='"+request.getContextPath()+"/addCart?id="+book.getKey()+"' >"+book.getValue().getName()+"</a><br/>");
}
//點選連結檢視購物車,關聯一個Servlet
out.print("<a href='"+request.getContextPath()+"/showCart"+"'>檢視購物車</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 下面是新增商品的Servlet,在這個Servlet中,需要獲取HttpSession,往裡面存放的代表購物車的List中新增商品,然後再將List放回HttpSession中。
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
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 entity.Book;
import util.DBUtil;
public class AddCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse