使用Cookie实现用户商品历史浏览记录
该功能分为四个模块:
1. 获取所有商品并以链接的形式显示
1 out.write("网站商品: <br/>"); 2 Map<String, Book> books = Db.getAll(); 3 for (Map.Entry<String, Book> me : books.entrySet()) { 4 String id = me.getKey(); 5 Book book = me.getValue(); 6 out.write("<a href='/test/servlet/CookieDemo3?id="+ id +"'>"+ book.getName() +"</a><br/>"); 7 }
模拟数据库和用户实体
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 模拟数据库 2 class Db { 3 4 // 要求: 1有序 2查找 -> LinkedHashMap 5 private static Map<String, Book> map = new LinkedHashMap<String, Book>(); 6 7 // 初始化map 8 static { 9 map.put("1", new Book("JavaWeb秘籍", 12.45)); 10 map.put("2", new Book("Spring开发", 45.5)); 11 map.put("3", new Book("SpringMVC开发", 82.45)); 12 map.put("4", new Book("Mybatis开发", 75.5)); 13 } 14 15 public static Map<String, Book> getAll() { 16 return map; 17 } 18 } 19 20 // 商品实体 21 class Book { 22 23 private String name; 24 private double price; 25 26 public Book(String name, double price) { 27 this.name = name; 28 this.price = price; 29 } 30 31 public String getName() { 32 return name; 33 } 34 35 public void setName(String name) { 36 this.name = name; 37 } 38 39 public double getPrice() { 40 return price; 41 } 42 43 public void setPrice(double price) { 44 this.price = price; 45 } 46 }
2. 显示用户上次浏览过的商品
通过用户携带的cookie显示用户历史浏览记录
1 out.write("<br/>上次浏览过的商品: <br/>"); 2 Cookie[] cookies = req.getCookies(); 3 for (int i = 0; cookies != null && i < cookies.length; i++) { 4 if (cookies[i].getName().equals("bookhistory")) { 5 String bookhistoryValue = cookies[i].getValue(); // 1_4_3 6 String[] ids = bookhistoryValue.split("\\_"); // [1, 4, 3] 7 // 迭代浏览过的商品id 8 for (String id : ids) { 9 out.write(Db.getAll().get(id).getName() + "<br/>"); 10 } 11 } 12 }
说明: 第一步和第二步可以做成同一个servlet中, 完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * Created by IntelliJ IDEA. 3 * 4 * @Auther: ShaoHsiung 5 * @Date: 2018/8/28 10:12 6 * @Title: 显示用户上次浏览商品 7 * @Description: 主页 8 */ 9 public class CookieDemo2 extends HttpServlet { 10 @Override 11 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 12 13 // 设置浏览器编码 14 resp.setContentType("text/html; charset=utf-8"); 15 16 Writer out = resp.getWriter(); 17 18 // 获取所有商品并以链接的形式显示 19 out.write("网站商品: <br/>"); 20 Map<String, Book> books = Db.getAll(); 21 for (Map.Entry<String, Book> me : books.entrySet()) { 22 String id = me.getKey(); 23 Book book = me.getValue(); 24 out.write("<a href='/test/servlet/CookieDemo3?id="+ id +"'>"+ book.getName() +"</a><br/>"); 25 } 26 27 // 显示用户上次浏览过的商品 28 out.write("<br/>上次浏览过的商品: <br/>"); 29 Cookie[] cookies = req.getCookies(); 30 for (int i = 0; cookies != null && i < cookies.length; i++) { 31 if (cookies[i].getName().equals("bookhistory")) { 32 String bookhistoryValue = cookies[i].getValue(); // 1_4_3 33 String[] ids = bookhistoryValue.split("\\_"); // [1, 4, 3] 34 // 迭代浏览过的商品id 35 for (String id : ids) { 36 out.write(Db.getAll().get(id).getName() + "<br/>"); 37 } 38 } 39 } 40 } 41 42 @Override 43 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 44 doGet(req, resp); 45 } 46 } 47 48 // 模拟数据库 49 class Db { 50 51 // 要求: 1有序 2查找 -> LinkedHashMap 52 private static Map<String, Book> map = new LinkedHashMap<String, Book>(); 53 54 // 初始化map 55 static { 56 map.put("1", new Book("JavaWeb秘籍", 12.45)); 57 map.put("2", new Book("Spring开发", 45.5)); 58 map.put("3", new Book("SpringMVC开发", 82.45)); 59 map.put("4", new Book("Mybatis开发", 75.5)); 60 } 61 62 public static Map<String, Book> getAll() { 63 return map; 64 } 65 } 66 67 // 商品实体 68 class Book { 69 70 private String name; 71 private double price; 72 73 public Book(String name, double price) { 74 this.name = name; 75 this.price = price; 76 } 77 78 public String getName() { 79 return name; 80 } 81 82 public void setName(String name) { 83 this.name = name; 84 } 85 86 public double getPrice() { 87 return price; 88 } 89 90 public void setPrice(double price) { 91 this.price = price; 92 } 93 }
3. 显示商品详细信息
通过请求参数在数据库中查询商品
1 out.write("商品详细信息: <br/>"); 2 String id = req.getParameter("id"); 3 Book book = Db.getAll().get(id); 4 out.write(book.getName() + "<br/>"); 5 out.write(book.getPrice() + "<br/>");
4. 将商品的id添加到cookie中并返回给用户
这里使用makeCookie()方法封装商品历史记录cookie的制作, 这部分主要任务就是将cookie返回给浏览器
1 String bookhistoryValue = makeCookie(req, id); 2 Cookie bookhistory = new Cookie("bookhistory", bookhistoryValue); 3 bookhistory.setMaxAge(3600); 4 bookhistory.setPath(this.getServletContext().getContextPath()); 5 resp.addCookie(bookhistory);
5. 完成makeCookie()方法
使用字符串拼接的方式产生cookie的具体步骤, 特别需要注意四种可能获取到的cookie及其处理方式.
注意: 四种可能获取到的cookie:
获取到的cookie 查看商品 返回的cookie
null 1 1
1_2_3 4 4_1_2
1_2_3 2 2_1_3
1_2 4 1_2_4
1 private String makeCookie(HttpServletRequest req, String id) { 2 String bookhistoryValue = null; 3 Cookie[] cookies = req.getCookies(); 4 for (int i = 0; cookies != null && i < cookies.length; i++) { 5 if (cookies[i].getName().equals("bookhistory")) { 6 bookhistoryValue = cookies[i].getValue(); 7 } 8 } 9 10 // null 1 1 11 if (bookhistoryValue == null) { 12 return id; 13 } 14 List l = Arrays.asList(bookhistoryValue.split("\\_")); 15 // 转化为链表方便操作, 提供addFirst和removeLast等方法 16 LinkedList<String> list = new LinkedList(); 17 list.addAll(l); 18 if (list.contains(id)) { 19 // 1_2_3 2 2_1_3 20 list.remove(id); 21 list.addFirst(id); 22 } else { 23 // 1_2_3 4 4_1_2 24 if (list.size() == 3) { 25 list.removeLast(); 26 list.addFirst(id); 27 } else { 28 // 1_2 4 1_2_4 29 list.addFirst(id); 30 } 31 } 32 StringBuffer buffer = new StringBuffer(); 33 for (String newId : list) { 34 buffer.append(newId + "_"); // 1_5_3_ 35 } 36 return buffer.deleteCharAt(buffer.length()-1).toString(); // 删除最后一个下划线 37 }
说明: 同理, 第三步和第四步可以做成同一个servlet中, 完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * Created by IntelliJ IDEA. 3 * 4 * @Auther: ShaoHsiung 5 * @Date: 2018/8/28 10:12 6 * @Title: 显示用户上次浏览商品 7 * @Description: 商品详细信息页面 8 */ 9 public class CookieDemo3 extends HttpServlet { 10 @Override 11 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 12 13 resp.setContentType("text/html; charset=utf-8"); 14 15 Writer out = resp.getWriter(); 16 17 // 显示商品详细信息 18 out.write("商品详细信息: <br/>"); 19 String id = req.getParameter("id"); 20 Book book = Db.getAll().get(id); 21 out.write(book.getName() + "<br/>"); 22 out.write(book.getPrice() + "<br/>"); 23 24 // 将商品的id添加到cookie中并返回给用户 25 String bookhistoryValue = makeCookie(req, id); 26 Cookie bookhistory = new Cookie("bookhistory", bookhistoryValue); 27 bookhistory.setMaxAge(3600); 28 bookhistory.setPath(this.getServletContext().getContextPath()); 29 resp.addCookie(bookhistory); 30 } 31 32 private String makeCookie(HttpServletRequest req, String id) { 33 34 String bookhistoryValue = null; 35 36 Cookie[] cookies = req.getCookies(); 37 for (int i = 0; cookies != null && i < cookies.length; i++) { 38 if (cookies[i].getName().equals("bookhistory")) { 39 bookhistoryValue = cookies[i].getValue(); 40 } 41 } 42 43 /* 44 重点: 四种情况 45 46 获取到的cookie 查看商品 返回的cookie 47 null 1 1 48 1_2_3 4 4_1_2 49 1_2_3 2 2_1_3 50 1_2 4 1_2_4 51 */ 52 53 // null 1 1 54 if (bookhistoryValue == null) { 55 return id; 56 } 57 58 59 List l = Arrays.asList(bookhistoryValue.split("\\_")); 60 // 转化为链表方便操作, 提供addFirst和removeLast等方法 61 LinkedList<String> list = new LinkedList(); 62 list.addAll(l); 63 if (list.contains(id)) { 64 // 1_2_3 2 2_1_3 65 list.remove(id); 66 list.addFirst(id); 67 } else { 68 // 1_2_3 4 4_1_2 69 if (list.size() == 3) { 70 list.removeLast(); 71 list.addFirst(id); 72 } else { 73 // 1_2 4 1_2_4 74 list.addFirst(id); 75 } 76 } 77 78 StringBuffer buffer = new StringBuffer(); 79 for (String newId : list) { 80 buffer.append(newId + "_"); // 1_5_3_ 81 } 82 83 return buffer.deleteCharAt(buffer.length()-1).toString(); // 删除最后一个下划线 84 } 85 86 @Override 87 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 88 doGet(req, resp); 89 } 90 }
效果图: