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