浅谈实现基于Javabean与JSP的购物车功能
 
 
  

 
  首先呢,在买了东西之后要放在购物车里,当车子里的物品有相同时就叠加,不再创建物品对象,有了物品之后肯 定要有价格,数量等等对象。这些对象我们要封装在JAVABEAN 中的!有了Javabean就需要建立SERVLET来进行与业务层连接,我们就需要有,增加购物车,删除购物车,清楚购物车等一系列的Servlet和SERVICE层连接!SERVICE层调用DAO层,这些步骤正体现出了MVC的设计模式!下面我们看具体的实现基于Javabean与JSP的购物车功能吧!
  (1) 1. 代表购物车的ShoppingCart 类
 
 
1. public class ShoppingCart {  
2.  //装载 ShoppingCartItem 的数据结构: Map, 键: 书的 id, 值: 书对应的 ShoppingCartItem  
3.  private Map<String, ShoppingCartItem> books = null;  
4. 
5.  public ShoppingCart(){  
6. books = new HashMap<String, ShoppingCartItem>();  
7.  }   
8. 
9.  public Map<String, ShoppingCartItem>
10.   return books;  
11.  }  
12. 
13.  public Book getBook(String bookId){  
14. book = null;  
15. 
16. sci = this.books.get(bookId);  
17. sci
18.    return null;  
19. 
20.   return sci.getBook ();  
21.  }  
22. 
23.  public float getTotalPrice(){  
24. totalPrice = 0.0f;  
25. 
26.   //对 books 中的 value 进行遍历, 取其 price 属性的和   
27.   Iterator<ShoppingCartItem> iterator = books.values().iterator ();  
28.   while(iterator.hasNext()){  
29. sci = iterator.next();  
30.    totalPrice += sci.getPrice();  
31.   }   
32. 
33.   return totalPrice;  
34.  }  
35. 
36.  public int getTotalQuantity(){  
37. quantity = 0;  
38. 
39.   //对 books 中的 value 进行遍历, 取其 quantity 属性的和  
40.   Iterator<ShoppingCartItem> iterator = books.values().iterator();  
41.   while(iterator.hasNext()) {  
42. sci = iterator.next();  
43.    quantity += sci.getQuantity();  
44.   }  
45. 
46.   return quantity;  
47.  }   
48. 
49.  public boolean isExistInShoppingCart(String bookId){  
50.   return this.books.get(bookId) != null;  
51.  }  
52. 
53.  public ShoppingCartItem getShoppingCartItemByBookId(String bookId){  
54.   return this.books.get(bookId);  
55.  }   
56. 
57.  public void addNewItemToShoppingCart(ShoppingCartItem sci) {  
58.   this.books.put(sci.getBook().getId(), sci);  
59.  }  
60. } 
 
 
2. 代表购物车中的物品
 
 
1. public class ShoppingCartItem {  
2.  //具体指向某本书  
3.  private Book book;  
4. 
5.  //当前商品在购物车中的数量  
6.  private int quantity;  
7. 
8.  public ShoppingCartItem(Book book) {  
9. this.book
10. this.quantity = 1;  
11.  }  
12. 
13.  //当前商品的总价格  
14.  private float price;  
15. 
16.  public void incrementQuantity(){  
17.   this.quantity++;  
18.  }  
19. 
20.  public Book getBook() {  
21.   return book;  
22.  }  
23. 
24.  public void setBook(Book book) {  
25. this.book
26.  }  
27. 
28.  public int getQuantity() {  
29.   return quantity;  
30.  }  
31. 
32.  public void setQuantity(int quantity) {  
33. this.quantity
34.  }   
35. 
36.  public float getPrice() {  
37.   return this.book.getPrice() * this.quantity;  
38.  }  
39. 
40. } 
 
 
(2)建立DAO,此时有人会问,这次DAO为什么没有购物车呢,因为购物车是没有数据的,而是里面的物品才有 数据的,当有更新购物车里面的物品时才会早DAO里面写方法!
 
 
1. public class BookDAO {  
2. 
3.  //  
4.  public void upadateBookQuantityByBookId(Connection conn, String bookId, int quantity){  
5. sql = "UPDATE books SET saleAmount = saleAmount + ? WHERE id = ?";  
6. params = new
7. 
8. queryRunner = new
9. 
10.   try {  
11.    queryRunner.update(conn, sql, params);  
12.   } catch (SQLException e) {  
13.    // TODO Auto-generated catch block  
14.    e.printStackTrace();  
15.    throw new RuntimeException (MyBookStoreConstants.UPDATE_BOOK_SALEAMOUNT_BY_BOOK_ID_EXCEPTION);  
16.   }  
17.  } 
 
 
(3) 建立业务层,涉及到添加,清空等方法!这边佟刚老师的代码都有详细的解释!
 
 
1. public class BookService {  
2.  //根据给定的 ShoppingCart 对象, 调用 DAO 方法进行数据库更新操作  
3.  public void buyBooks(ShoppingCart sc){  
4.   //对 sc 中的 ShoppingCartItem 对象进行遍历, 调用 BookDAO.upadateBookQuantityByBookId 方法  
5. conn = null;  
6. conn = DBHelper.getConnection();  
7. 
8.   try {  
9.    Iterator<ShoppingCartItem> shoppingCartItemSet = sc.getBooks().values ().iterator();  
10. bookDAO = new
11. 
12.    while(shoppingCartItemSet.hasNext()) {  
13. sci = shoppingCartItemSet.next ();  
14. 
15. bookId = sci.getBook().getId ();  
16. quantity = sci.getQuantity ();  
17. 
18.     bookDAO.upadateBookQuantityByBookId(conn, bookId, quantity);  
19.    }  
20.   }finally {  
21.    DBHelper.releaseDBSource(null, null, conn);  
22.   }   
23. 
24. 
25.  }  
26. 
27.  //参数 items 中的键为 书的 id 号, 值为购 物车中对应的 数量  
28.  public void updateShoppingCart(Map<String,Integer>
29.   Set<String> keySet = null;  
30. keySet = items.keySet ();  
31. 
32.   for(Iterator<String> it = keySet.iterator(); it.hasNext(); ) {  
33. bookId = it.next();  
34. quantity = items.get (bookId);  
35. 
36. <= 0) {  
37.     sc.getBooks().remove(bookId);  
38.    }else {  
39.     sc.getShoppingCartItemByBookId(bookId).setQuantity (quantity);  
40.    }  
41. 
42.   }  
43.  }   
44. 
45.  //清空购物车  
46.  public void clearShoppingCart(ShoppingCart sc) {  
47.   sc.getBooks().clear();  
48.  }  
49. 
50.  public void deleteShoppingCartItemById(String id, ShoppingCart sc){  
51.   //删除 sc 中的 id 元素   
52.   sc.getBooks().remove(id);  
53.  }  
54. 
55.  //把 id 对应的 ShoppingCartItem 对象放入购物车 ShoppingCart 对象中  
56.  public void addToShoppingCart(String id, ShoppingCart sc) {  
57. 
58.   //1. 查看 sc 中有没有 id 对应的 ShoppingCartItem 对象   
59.   if(sc.isExistInShoppingCart(id)){  
60.    //1.1 有: 把该对象取出, 使其数量 + 1, 调用 sci.increseQuantity(); 方法  
61. scsci
62.    sci.incrementQuantity();  
63.   }   
64.   //1.2 没有: 创建一个新的 ShoppingCartItem 对象, 并将其放入 sc 中, 以书的 id 作为键   
65.   else{  
66.    //1.2.1 根据 id 获取相应的 Book 对象, 调用 BookDAO 的 selectBookByBookId() 方法  
67. book = null;  
68. bookDAO = null;  
69. 
70. bookDAO = new
71. book = bookDAO.selectBookByBookId(id);  
72. 
73. sci = null;  
74. sci = new
75. 
76.    sc.addNewItemToShoppingCart(sci);  
77.   }   
78.  }  
79. } 
 
 
(4)这段是 检查购物车是有对象的,这里单独拿出来是可以很好的在WEB开发中很好的进行重用 的。
 
 
1. public class MyBookStoreUtils {  
2.  private MyBookStoreUtils(){}  
3. 
4.  public static  ShoppingCart getShppingCartForCreateOrExist(HttpServletRequest request) {  
5. sc = null;  
6.   //2.1 检查在 HttpSession 对象中有没有购物车对象 , 即检查 session 中是否有 MyBookStoreConstants.SHOOPING_CART_KEY 属性  
7.   //   若 已经存在, 说明购物车存在, 直接取出  
8. session = null;  
9. session = request.getSession();  
10. 
11. obj = session.getAttribute (MyBookStoreConstants.SHOOPING_CART_KEY);  
12. 
13.   if(obj != null) {  
14. sc
15.   }  
16.   //2.2 若不存在 MyBookStoreConstants.SHOOPING_CART_KEY 属性, 创建一个购物车对象, 并把该对象放入 Session 中   
17.   else{  
18. sc = new
19.    session.setAttribute(MyBookStoreConstants.SHOOPING_CART_KEY, sc);  
20.   }  
21. 
22.   return sc;  
23.  }  
24. 
25.  public static  ShoppingCart getShppingCartForExist(HttpServletRequest request) {  
26. sc = null;  
27.   //2.1 检查在 HttpSession 对象中有没有购物车对象 , 即检查 session 中是否有 MyBookStoreConstants.SHOOPING_CART_KEY 属性  
28.   //   若 已经存在, 说明购物车存在, 直接取出  
29. session = null;  
30. session = request.getSession();  
31. 
32. obj = session.getAttribute (MyBookStoreConstants.SHOOPING_CART_KEY);  
33. 
34.   if(obj != null) {  
35. sc
36.   }  
37.   //2.2 若不存在 MyBookStoreConstants.SHOOPING_CART_KEY 属性, 抛出异常, 提示用户还不存在购物车.  
38.   else {  
39.    throw new RuntimeException (MyBookStoreConstants.NO_SHOPPING_CART_EXCETPION);  
40.   }   
41. 
42.   return sc;  
43.  }  
44. } 
 
 
(5)这里是所有与购物车相关的SERVLET.
这个是更新数据的,需要在SERVICE中调用DAO的!
 
 
1. public class UpdateShoppingCartServlet extends HttpServlet {  
2. 
3.  public void doPost(HttpServletRequest request, HttpServletResponse response)   
4.    throws ServletException, IOException {  
5.   //获取表单信息   
6.   // request.getParameter(""); 方法行不通, 因为表单的 name 是随时变化的   
7. 
8.   //获取表单中的所有 name  
9.   Enumeration<String> nameEnums = request.getParameterNames();  
10. 
11. items = new HashMap<String, Integer>();  
12.   //遍历 nameEnums, 再取出对应的 Value, 封装到 items 中   
13. 
14.   try {  
15.    while(nameEnums.hasMoreElements()) {  
16. bookId = nameEnums.nextElement();  
17. quantity = request.getParameter (bookId);  
18. 
19.     items.put(bookId, Integer.parseInt (quantity));  
20.    }  
21.   } catch (NumberFormatException e) {  
22.    // TODO Auto-generated catch block  
23.    e.printStackTrace ();  
24.    throw new RuntimeException (MyBookStoreConstants.QUANTITY_FORMAT_EXCEPTION);  
25.   }  
26. 
27.   //获 取购物车对象  
28. sc = null;  
29. sc = MyBookStoreUtils.getShppingCartForExist(request);  
30. 
31.   //调用 Service 方法   
32. bookService = new
33.   bookService.updateShoppingCart(items, sc);  
34. 
35.   //派发页面 : showShoppingCart.jsp 页面  
36. forwardPage = "/WEB- INF/jsp/showShoppingCart.jsp";  
37.   request.getRequestDispatcher(forwardPage).forward (request, response);  
38.  }  
39. 
40. }  
41. 
42. public class ShowShoppingCartServlet extends HttpServlet {  
43. 
44.  public void doGet(HttpServletRequest request, HttpServletResponse response)   
45.    throws ServletException, IOException {  
46.   //做一个转发   
47. forwardPage = null;  
48. 
49. forwardPage = "/WEB- INF/jsp/showShoppingCart.jsp";  
50. 
51. dispatcher = null;  
52. dispatcher = request.getRequestDispatcher (forwardPage);  
53.   dispatcher.forward(request, response);  
54.  }  
55. 
56. }  
57. public class ReceiptServlet extends HttpServlet {  
58. 
59.  public void doPost(HttpServletRequest request, HttpServletResponse response)   
60.    throws ServletException, IOException {  
61.   //1. 获取表单信息: name 和 cardId  
62. 
63.   //2. 调用 Service 方法, 更新 books 表各条 book 的 saleAmount 字段   
64. 
65.   //2.1 获取购物车  
66. sc = MyBookStoreUtils.getShppingCartForExist(request);  
67. 
68. bookService = new
69.   bookService.buyBooks (sc);  
70. 
71.   //2.1 使 Session 失效  
72. session = null;  
73. session = request.getSession();  
74.   session.invalidate ();  
75. 
76.   //3. 派发页面: receipt.jsp 页面   
77.   request.getRequestDispatcher("/WEB-INF/jsp/receipt.jsp").forward(request, response);   
78.  }  
79. } 
 
 
这段我先开始很纳闷老师为什么会这样写呢,其实很简单,写个专门的转发的SERVLET这样,在每次转发的时候就只连接一个servlet比连接多个更来的简洁!提高了效率!
 
 
1. public class ForwardServlet extends HttpServlet {  
2. 
3.  public void doGet(HttpServletRequest request, HttpServletResponse response)   
4.    throws ServletException, IOException {  
5.   //1. 获取 path  
6. path = request.getParameter("path");  
7. 
8.   //2. 派 发页面  
9.   request.getRequestDispatcher(path).forward(request, response);  
10.  }  
11. 
12. }  
13. public class DeleteShoppingCartItemServlet extends HttpServlet {  
14. 
15.  public void doGet(HttpServletRequest request, HttpServletResponse response)   
16.    throws ServletException, IOException {  
17.   //1. 获取 id 号   
18. id = request.getParameter("bookid");  
19. 
20.   //2. 调用 BookService 方法 deleteShoppingCartItemById:, 进行删除操作  
21. sc = MyBookStoreUtils.getShppingCartForExist(request);  
22. 
23. bookTitle = sc.getBook(id).getTitle();  
24. 
25. bookService = new
26.   bookService.deleteShoppingCartItemById(id, sc);  
27. 
28.   //3. 派发页面  
29.   request.setAttribute(MyBookStoreConstants.DELETE_FROM_SHOPPING_CART_BOOK_TITLE, bookTitle);  
30. 
31. forwardPage = "/WEB- INF/jsp/showShoppingCart.jsp";  
32.   //4. 判断购物车是否为空, 若为空则派发到 emptyCart.jsp 页面  
33.   if(sc.getBooks().isEmpty())  
34. forwardPage = "/WEB- INF/jsp/emptyCart.jsp";  
35. 
36. dispatcher = null;  
37. dispatcher = request.getRequestDispatcher (forwardPage);  
38.   dispatcher.forward(request, response);  
39.  }  
40.  } 
 
 
这里是清空购物车的SERVLET.
 
 
1. public class ClearShoppingCartServlet extends HttpServlet {  
2. 
3.  public void doGet(HttpServletRequest request, HttpServletResponse response)   
4.    throws ServletException, IOException {  
5.   //1. 调用方法   
6. bookService = new
7. 
8. sc = null;  
9. sc = MyBookStoreUtils.getShppingCartForExist (request);  
10. 
11.   bookService.clearShoppingCart (sc);  
12. 
13.   //2. 派发页面  
14. forwardPage = null;  
15. forwardPage = "/WEB- INF/jsp/emptyCart.jsp";  
16. 
17. dispatcher = request.getRequestDispatcher(forwardPage);  
18.   dispatcher.forward(request, response);  
19.  }  
20. 
21. }  
22. public class AddToShoppingCartServlet extends HttpServlet {  
23. 
24.  public void doGet(HttpServletRequest request, HttpServletResponse response)   
25.    throws ServletException, IOException {  
26. 
27. 
28.   //1. 获取书的 id 号  
29. bookId = null;  
30. bookId = request.getParameter("bookId");  
31. 
32.   //2. 获取 购物车对象: 调用 getShppingCart 方法  
33. sc = null;  
34. sc = MyBookStoreUtils.getShppingCartForCreateOrExist(request);  
35. 
36.   //3. 调用 Service 方法把 id 对应的 ShoppingCartItem 对象放入购物车 ShoppingCart 对象中: addToShoppingCart(id, shoppingCart);  
37. bookService = null;  
38. bookService = new
39. 
40.   bookService.addToShoppingCart(bookId, sc);  
41. 
42.   //4. 派发页面  
43. forwardPage = "/index.jsp";  
44. 
45.   //4.1 获取书名  
46. bookTitle = null;  
47. bookTitle = sc.getBooks().get(bookId).getBook().getTitle ();  
48. bookTitle = sc.getBook(bookId).getTitle();  
49. 
50.   //4.2 将书 名放入请求域中, 以让页面进行显示  
51.   request.setAttribute (MyBookStoreConstants.ADD_TO_SHOPPING_CART_BOOK_TITLE, bookTitle);  
52. 
53. dispatcher = null;  
54. dispatcher = request.getRequestDispatcher (forwardPage);  
55.   dispatcher.forward(request, response);  
56.  }  
57. 
58. } 
 
 
(6)下面是显示层,对应着其相应的SERVLET.下面的JSP页面运用到了我们前段时间学的JSTL,EL表示.
'cashier.jsp'1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% >
2. 
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4. <html> 
5. <head> 
6. <title>My JSP 'cashier.jsp' starting page</title> 
7. </head> 
8. 
9. <body> 
10. <center> 
11. <br><br> 
12. 您一共购买 了 ${sessionScope.shoppingcartkey.totalQuantity} 本书 
13. <br><br> 
14. 您应付金额 是:${sessionScope.shoppingcartkey.totalPrice} 元。 
15. <br><br> 
16. <form action="receiptServlet" method="POST">
17. <table> 
18. <tr> 
19. <td>信用卡用户 名:</td> 
20. <td><input type="text" name="userName"/></td> 
21. </tr> 
22. <tr> 
23. <td>信用卡帐号:</td> 
24. <td><input type="text" name="cardId"/></td> 
25. </tr> 
26. <tr align="center">
27. <td colspan="2">
28. <input type="submit" value="递交 "/>
29. </td> 
30. </tr> 
31. </table> 
32. </form> 
33. </center> 
34. </body> 
35. </html> 
36. 'receipt.jsp' 
37. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
38. 
39. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
40. <html> 
41. <head> 
42. <title>My JSP 'emptyCart.jsp' starting page</title> 
43. </head> 
44. 
45. <body> 
46. <center> 
47. <br><br> 
48. 您的购物车 为空<br><br> 
49. <a href="${pageContext.request.contextPath }/index.jsp">继续购物<a> 
50. </center> 
51. </body> 
52. </html> 
53. <%@ page language="java" import="java.util.*" pageEncoding="UTF- 8"%>
54. 
55. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
56. <html> 
57. <head> 
58. <title>My JSP 'receipt.jsp' starting page</title> 
59. </head> 
60. 
61. <body> 
62. 再见: ${param.userName }<br><br> 
63. <a href="${pageContext.request.contextPath }/index.jsp">继续购物</a>   
64. </body> 
65. </html> 
66. 
67. 'showShoppingCart.jsp' 
68. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% >
69. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
70. 
71. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
72. <html> 
73. <head> 
74. <title>My JSP 'showShoppingCart.jsp' starting page</title> 
75. </head> 
76. 
77. <body> 
78. <center> 
79. <c:if test="${requestScope.deleteToShoppingCartBookTitle != null}">
80. <br><br> 
81. 您已经把 ${requestScope.deleteToShoppingCartBookTitle} 从购物车中删除了! 
82. </c:if> 
83. <br><br> 
84. 您的购物车中一共有 ${sessionScope.shoppingcartkey.totalQuantity} 本书 
85. <br><br> 
86. <form action="updateShoppingCartServlet" method="POST">
87. <table cellpadding="10" cellspacing="0">
88. <tr> 
89. <th>书名</th> 
90. <th>价 格</th> 
91. <th>数量 </th> 
92. <td></td> 
93. </tr> 
94. <c:forEach items="${sessionScope.shoppingcartkey.books}" var="sci">
95. <tr> 
96. <td>${sci.value.book.title }</td> 
97. <td>${sci.value.book.price }</td> 
98. <td><input type="text" value="${sci.value.quantity }" name="${sci.key }" size="2" /></td> 
99. <td><a href="${pageContext.request.contextPath }/deleteShoppingCartItemServlet?bookid=${sci.key }">删除 </a></td> 
100. <td></td> 
101. </tr> 
102. </c:forEach> 
103. </table> 
104. <input type="submit" value="保存修 改">
105. </form> 
106. <br> 
107. 总价格: ${sessionScope.shoppingcartkey.totalPrice} 
108. <br><br> 
109. <a href="${pageContext.request.contextPath }/index.jsp">继续购物 </a>   
110. <a href="${pageContext.request.contextPath }/clearShoppingCartServlet">清空购物车 </a>   
111. <a href="${pageContext.request.contextPath }/forwardServlet?path=cashier.jsp">付账 </a> 
112. </center> 
113. </body> 
114. </html> 
  这样子简易JSP购物车算是完成了,当然这个JSP购物车只是简单的运用,没有涉及到大量的数据,作为入门的教学的例子是完全值得我们这些初学者消化的了!通过这次JSP购物车的联系,我对MVC的设计模式有了深刻的了解!不过其中的一些细节,还是需要我自己去慢慢的体会的!比如分页就是一个值得我去好好去研究的例子!