手把手做一个JSP入门程序(九):购物车的基本实现(Servlet)

购物车类及购物车DAO

购物车

  该类也是一个JavaBean,除了普通Getter和Setter,这里还实现了一个获取单种书籍的总费用的方法。我们利用一个以书本对象为Key,以相应书本数量为value的HashMap存放购物中的所有书本。这样就可以有效的表示购物车中的书本及其数目。
entiry.Cart.java

package entity;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class Cart {
//  车里会有很多的商品,所以我们可以用一个Map存放起来
//  商品集合
    private HashMap<Book, Integer> books;

    public Cart(){}

    public HashMap<Book, Integer> getBooks() {
        return books;
    }

    public void setBooks(HashMap<Book, Integer> books) {
        this.books = books;
    }

    public double getOneTypeBookCostInCart(Book book){
        return book.getPrice()* books.get(book);
    }
}

购物车DAO

  对操作逻辑进行必要的分析,我们可以知道UserDAO需要有如下方法:

  • 判断购物车中是否已有选中书本,用于判断是插入数据还是更新数据
  • 添加书本
  • 删除书本
  • 获取用户购物车

  在购物车中,我们通过uid和isbn对一本书进行确定,也就确定是谁的购物车,哪一本书。在添加一本书中,我们需要先判断购物车中是否已有该书,有则更新数据,没有则插入一条记录。

dao.CartDAO.java

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

import entity.Book;
import entity.Cart;
import util.DBHelper;

public class CartDAO {
//  判断是否已有该书
    public String isExist(String uid, String isbn){
        Connection conn = null;
        PreparedStatement preStmt = null;
        ResultSet userSet = null;
        System.out.println("添加书本");
        try{
            conn = DBHelper.getConnection();
//          判断商品是否已经存在
            String sql = "select * from cart where uid=? and isbn=?";
            preStmt = conn.prepareStatement(sql);
            preStmt.setString(1, uid);
            preStmt.setString(2, isbn);
            userSet = preStmt.executeQuery();

            if(userSet.next()){
                return "true";
            }
            return "false";
        }catch(Exception ex){
            ex.printStackTrace();
            return "error";
        }finally{
            if(preStmt != null){
                try {
                    preStmt.close();
                    preStmt = null;
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
//  添加商品
    public boolean addBook(String uid, String isbn, int num){
        Connection conn = null;
        PreparedStatement preStmt = null;
        ResultSet userSet = null;
        System.out.println("添加书本");
        try{
            conn = DBHelper.getConnection();
//          判断商品是否已经存在
            String exist = isExist(uid, isbn);
            if(exist == "error"){
                return false;
            }if(exist == "false"){
                String sql = "insert into cart(uid, isbn, num) values(?, ?, ?)";
                preStmt = conn.prepareStatement(sql);
                preStmt.setInt(3, num);
            }else if(exist == "true"){
                String sql = "update cart set num=num+1 where uid=? and isbn=?";
                preStmt = conn.prepareStatement(sql);
            }
            preStmt.setString(1, uid);
            preStmt.setString(2, isbn);
            int affectedRowNum = preStmt.executeUpdate();
            if(affectedRowNum > 0){
                return true;
            }
            else{
                return false;
            }
        }catch(Exception ex){
            ex.printStackTrace();
            return false;
        }finally{
            if(preStmt != null){
                try {
                    preStmt.close();
                    preStmt = null;
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
//  添加一件商品
    public boolean addOneBook(String uid, String isbn){
        System.out.println("添加一本书");
        return addBook(uid, isbn, 1);
    }
//  删除商品
    public boolean deleteBook(String uid, String isbn){
        Connection conn = null;
        PreparedStatement preStmt = null;

        try{
            conn = DBHelper.getConnection();
            String sql = "delete from cart where uid=? and isbn=?";
            preStmt = conn.prepareStatement(sql);
            preStmt.setString(1, uid);
            preStmt.setString(2, isbn);

            int affectedRowNum = preStmt.executeUpdate();

            if(affectedRowNum < 1){
                return false;
            }
            return true;
        }catch(Exception ex){
            ex.printStackTrace();
            return false;
        }finally{
            if(preStmt != null){
                try{
                    preStmt.close();
                    preStmt = null;
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
        }
    }

//  获取用户购物车
    public Cart getCart(String uid){
        Connection conn = null;
        PreparedStatement preStmt = null;
        ResultSet bookSet = null;
        Cart cart = null;
        try{
            conn = DBHelper.getConnection();
            String sql = "select B.name, B.isbn, B.price, C.num from book B, Cart C where B.isbn = C.isbn and C.uid = ?";
            preStmt = conn.prepareStatement(sql);
            preStmt.setString(1, uid);
            bookSet = preStmt.executeQuery();
            HashMap<Book, Integer> books = new HashMap<Book, Integer>();
            double tolalCost = 0;
            while(bookSet.next()){
                Book book = new Book();

                book.setName(bookSet.getString("name"));
                book.setIsbn(bookSet.getString("isbn"));
                float price = bookSet.getFloat("price");
                book.setPrice(price);
                int num = Integer.parseInt(bookSet.getString("num"));
                books.put(book, num);
                tolalCost += price * num;
            }
            cart = new Cart();
            cart.setBooks(books);
            cart.setTotalCost(tolalCost);
            return cart;
        }catch(Exception ex){
            ex.printStackTrace();
            return null;
        }finally{
            if(bookSet != null){
                try{
                    bookSet.close();
                    bookSet = null;
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
            if(preStmt != null){
                try{
                    preStmt.close();
                    preStmt = null;
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
        }
    }
}

添加商品

前端修改与ajax请求

  我们点击[Add To Cart]按钮,网页会通过ajax异步请求服务器,然后根据服务器返回的数据以模态框的方式显示提示信息(成功与否)。为了满足这个功能,我们需要修改index.jsp代码,之前的代码另存为了index-before.jsp。

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import="entity.Book" %>
<%@ page import="dao.BookDAO" %>
<%@ include file="header.jsp" %>
    <div class="main">
        <!-- 模态框(Modal) -->
        <div class="modal fade" id="addAlert" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-sm">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                        <h4 class="modal-title" id="myModalLabel">提示</h4>
                    </div>
                    <div class="modal-body" id="addAlert-content">操作错误</div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    </div>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div>
        <div class="container-fluid">
            <div class="row">
            <%-- 通过BookDao获取数据库中的书籍数据 --%>
            <%
                BookDAO bookDao = new BookDAO();
                ArrayList<Book> books = bookDao.getAllBooks();
                if(books != null && books.size() > 0){
                    for(Book book:books){

            %>
                <div class="book-box col-md-3 col-sm-6">
                    <div class="book">
                        <a href="single.jsp?isbn=<%= book.getIsbn() %>"><img src="img/<%= book.getImg() %>"/></a>
                        <p class="book-name"><%= book.getName() %></p>
                        <p class="book-intro"><%= book.getIntro() %></p>

                        <div class="add-button">
                            <span class="cost"><%= book.getPrice() %></span> / <span class="cost-original">¥<%= book.getPrice_original() %></span>
                            <button class="add-btn" data-book-isbn="<%= book.getIsbn() %>">Add To Cart</button>
                        </div>
                    </div>
                </div>
            <%
                    }
                }
            %>
            </div>
        </div>
    </div>
<%@ include file="footer.jsp" %>

  除了添加一个模态框,按钮的修改非常的重要。该按钮中通过data存入了对应书本的isbn。

<button class="add-btn" data-book-isbn="<%= book.getIsbn() %>">Add To Cart</button>

  如下为点击按钮时异步请求服务器的代码。这里和其他所有的ajax异步编程都是一样的。注意提交的路径为:/SimpleShop/cart。在我们提交的数据中,包含两个字段,分别是isbn和操作类型的action,这里不同提交uid,uid可以在session中获得。.modal是bootstrap框架模态框的方法,这里是将id为addAlert的模态框显示出来。这时候应该思考的是:后台如何返回数据呢?

// 添加书本到购物车
$(".add-btn").click(function(){
    var isbn = $(this).data("book-isbn");
    $.ajax({
        url: "/SimpleShop/cart",
        type: "GET",
        dataType:"json",
        data: {
            isbn: isbn,
            action: "add"
        },
        success: function(result){
            $('#addAlert-content').text(result.message);
            $('#addAlert').modal('show');
        },
        error: function(result){
            $('#addAlert-content').text(result.message);
            $('#addAlert').modal('show');
        }
    });
});

Servlet处理请求输出,通过PrintWriter返回给ajax

  这里对于前端的异步请求,只需要将数据通过PrintWriter通过流的方式将数据返回即可。代码段格式如下。print中的内容是按照json的格式返回,以返回一个对象类型给前端。由于点击一次增加一本书,所以只要调用CartDAOaddOneBook方法即可,对于删除,我们只要调用deleteBook方法即可。是不是觉得封装了CartDAO,之后写代码就方便了很多呢!

//      确保返回的数据不乱码
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
if(user == null){
//      尚未登录
//      以json格式返回
    out.print("{\"err\":\"error\",\"message\":\"您尚未登录\"}");  
    out.flush();  
    out.close();
    return;
}

servlet.Cart.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dao.CartDAO;
import entity.User;

/**
 * Servlet implementation class Cart
 */
@WebServlet("/cart")
public class Cart extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Cart() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = (User)request.getSession().getAttribute("user");
//      确保返回的数据不乱码
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        if(user == null){
//          尚未登录
            out.print("{\"err\":\"error\",\"message\":\"您尚未登录\"}");  
            out.flush();  
            out.close();
            return;
        }
        String isbn = request.getParameter("isbn");
        String action = request.getParameter("action");

        String uid = user.getUid();

        if(action.equals("add")){
            CartDAO cartdao = new CartDAO();
            if(cartdao.addOneBook(uid, isbn)){
                out.print("{\"message\":\"添加成功\"}");
            }else{
                out.print("{\"message\":\"添加失败\"}");
            }
        }else if(action.equals("delete")){
            CartDAO cartdao = new CartDAO();
            if(cartdao.deleteBook(uid, isbn)){
                out.print("{\"err\":\"success\",\"message\":\"删除成功\"}");
            }else{
                out.print("{\"err\":\"fail\",\"message\":\"删除失败\"}");
            }
        }
        out.flush();  
        out.close();
//      不存在操作
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

显示购车

  购物车的商品只有在用户登录只有才会展示,所以这里也需要利用session中的user判断用户是否已经登录了,并根据不同的状态做出不同的处理。由于HashMap无法进行遍历,所以这里需要先取出其中的key值的Set集合,遍历该集合在利用get方法来实现对HashMap的遍历。这里注意delete上的数据,由于我们也需要用到ajax来实现删除,所以为了方便操作需要用data保存isbn,同时因为删除一本书之后,总价需要更新,减所以这里也用data保存了每种书需要的总花费,这样只要获取下来一减就可以了。
cart.jsp

<%@ page language="java" import="java.util.*"  contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="dao.CartDAO" %>
<%@ page import="entity.*" %>
<%@ include file="header.jsp" %>
    <div class="main main-white">
        <!-- 模态框(Modal) -->
        <div class="modal fade" id="deleteAlert" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-sm">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                        <h4 class="modal-title" id="myModalLabel">提示</h4>
                    </div>
                    <div class="modal-body" id="deleteAlert-content">操作错误</div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    </div>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div>
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
                    <%
                        User user = (User)session.getAttribute("user");
                if(user == null){
                    // 未登录
            %>
            <div class="withoutlogin-area">
              <p>您尚未登录,登录后将显示您购物车中商品</p>
            </div>
            <%
                }else{
          %>
          <div class="table-responsive table-shadow">
              <table class="table table-striped">
                <thead>
                <tr>
                  <th></th>
                  <th>商品名</th>
                  <th>单价(元)</th>
                    <th>数量</th>
                  <th>金额</th>
                  <th>操作</th>
                </tr>
                </thead>
                <tbody>
                <%
                    String uid = user.getUid();
                    CartDAO cartdao = new CartDAO();
                    Cart cart = cartdao.getCart(uid);

                    HashMap<Book,Integer> books = cart.getBooks();
                    Set<Book> bookSet = books.keySet();
                    Iterator<Book> it = bookSet.iterator();
                    double totalPrice = 0;
                    while(it.hasNext())
                    {
                        Book book = it.next();
                        double cost = cart.getOneTypeBookCostInCart(book);
                        totalPrice += cost;
                %>
                <tr>
                  <td><input type="checkbox" /></td>
                    <td><%= book.getName() %></td>
                  <td><%= String.format("%.2f",book.getPrice()) %></td>
                  <td><%=books.get(book) %></td>
                  <td><%= String.format("%.2f",cost)%></td>
                  <td><a href="javascript:void(0)" class="delete" data-cost="<%= cost %>" data-book-isbn="<%=book.getIsbn() %>">删除</a></td>
                </tr>
                <%
                        }
                %>
                </tbody>
                </table>
                </div>
                <div class="divider divider-light"></div>
                <div class="amount">
                    <div class="tag-left">
                        <input class="allchose" type="checkbox" />全选
                    </div>
                    <div class="tag-right">
                        总计:¥<span class="amount-cost"><%= String.format("%.2f",totalPrice) %></span><button type="submit" class="btn">提交订单</button>
                    </div>
                </div>
                <%
                }
                %>
                </div>
            </div>
        </div>
    </div>
<%@ include file="footer.jsp" %>

删除商品

ajax实现

$(".delete").click(function(){
    var isbn = $(this).data("book-isbn");
    var cost = $(this).data("cost");
    var $tr = $(this).closest("tr");
    $.ajax({
        url: "/SimpleShop/cart",
        type: "GET",
        dataType:"json",
        data: {
            isbn: isbn,
            action: "delete"
        },
        success: function(result){
            $('#deleteAlert-content').text(result.message);
            $('#deleteAlert').modal('show');
            if(result.err == "success"){
                $tr.fadeOut();
                $(".amount-cost").text(($(".amount-cost").text() - cost).toFixed(2));
            }
        },
        error: function(result){
            $('#deleteAlert-content').text(result.message);
            $('#deleteAlert').modal('show');
        }
    });
});

Servlet处理请求输出,通过PrintWriter返回给ajax

  只需要调用CartDAO中的deleteBook方法即可。具体实现见上面的商品添加。

  • 9
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值