1.为什么要实现历史记录功能
我们在访问淘宝,京东等购物网站的时候,系统会自动给我们保存刚才浏览过的商品信息。简单的说,你想要购买一件商品,你在搜索栏输入想要的商品名称,系统会显示所有包含商品名称的商品,此时你点开第一件商品,发现不太满意,又往下浏览,浏览到最后却发现还是第一次看的商品最好,但是如果没有历史记录的话,你就很难找到那件商品,有了历史记录以后,你就可以查找历史纪录中最早访问的商品了,从而找到最满意的一款
2.怎样实现历史纪录功能
毫无疑问,能存储信息的还是cookie。具体怎么实现呢,首先,因为cookie能够携带的信息有限加上cookie只能存储字符串,所以我们不能直接将商品对象存储到cookie中,我们可以以商品的编号代之。当访问一件商品时,客户端向服务器发送请求,服务器从数据库中拿数据显示到页面上,将商品的编号写回到cookie,再将cookie携带到客户端。在写这个程序的时候,我们需要写一个DBUtils工具类,返回值为HashMap<String, Object>,一个编号对应一个商品对象。当我们访问编号为1的商品时,1商品被保存到历史记录中,然后我们再访问2商品,此时在写回到cookie的时候,我们先将1商品拿出来,然后拼接到2商品的后面,此时变为2-1,再将2-1写回到cookie中。依次类推,当访问第三本书的时候,历史纪录中为3-2-1。由于我们要求历史记录中的商品不能重复,因此我们在访问第二本书的时候,需要先用split将字符串分割,依次遍历,将2去掉,在将剩下的3-1拼接到2的后面。
下面看具体的实现代码
先编写对应的实体类,并且生成对应的set、get方法
package edu.swpu.entity;
public class Book {
private String id;
private String name;
private double price;
private String author;
public Book(String id, String name, double price, String author) {
super();
this.id = id;
this.name = name;
this.price = price;
this.author = author;
}
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 double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + ", price=" + price
+ ", author=" + author + "]";
}
}
package edu.swpu.util;
import java.util.HashMap;
import java.util.Map;
import edu.swpu.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);
}
}
package edu.swpu.history;
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 edu.swpu.entity.Book;
import edu.swpu.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.write("本网站有以下好书:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
out.write("<a href='"+request.getContextPath()+"/servlet/showBookDetail?id="+book.getKey()+"' target='_blank'>"+book.getValue().getName()+"</a><br/>");
}
out.write("<hr/>您最近浏览过的书有:<br/>");
Cookie[] cookies = request.getCookies();
for(int i = 0; cookies != null && i < cookies.length; i++) {
if("historyBookId".equals(cookies[i].getName())){ //判断是否有historyBookId的cookie
String value = cookies[i].getValue(); //1-2-3
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);
}
}
package edu.swpu.history;
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 edu.swpu.entity.Book;
import edu.swpu.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
String id = request.getParameter("id");
Book book = DBUtil.findBookById(id);
//out.write(book.toString());
out.print(book);
//把当前浏览过的书的id写回到客户端
String historyBookId = organizeId(id, request);
Cookie ck = new Cookie("historyBookId", historyBookId);
ck.setPath("/");
ck.setMaxAge(Integer.MAX_VALUE); //设置cookie的保存时间
response.addCookie(ck); //写回到客户端
}
/**
* 客户端 showAllBooks showBookDetail
* 没有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;
}
String value = historyBook.getValue(); //2-1-3
String[] values = value.split("-");
LinkedList<String> list = new LinkedList<String>(Arrays.asList(values));
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));
}
System.out.println(sb); //1-2-3
return sb.toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}