1. 程式人生 > >Cookie和HttpSession的使用小案例

Cookie和HttpSession的使用小案例

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