购物车【JavaWeb小项目、简单版】

小编 2026-06-27 阅读:1479 评论:0
前言为了巩固MVC的开发模式,下面就写一个购物车的小案例..①构建开发环境导入需要用到的开发包建...

前言

为了巩固MVC的开发模式,下面就写一个购物车的小案例..

①构建开发环境

导入需要用到的开发包

购物车【JavaWeb小项目、简单版】

建立程序开发包

购物车【JavaWeb小项目、简单版】


②设计实体

书籍实体

    public class Book {            private String id;        private String name;        private String author;        private String description;        private double price;            public Book() {        }            public Book(String id, String name, String author, String description, double price) {            this.id = id;            this.name = name;            this.author = author;            this.description = description;            this.price = price;        }            //...各种setter和getter    }

购物车与购物项实体

可能我们会这样设计购物车

    /*该类代表的是购物车*/    public class Cart {            //关键字是书籍的id,值是书        private Map<String, Book> bookMap = new LinkedHashMap<>();            }

上面的做法是不合适的,试想一下:如果我要购买两本相同的书,购物车的页面上就出现了两本书,而不是书2。买三本相同的书就在购物页面上出现三本书,而不是书3.

因此,Map集合的值不能是Book对象,那我们怎么才能解决上面所说的问题呢?我们最常用的就是,再写一个实体CartItem(代表购物项)

  • 好的,我们先来写购物项实体吧,等会再写购物车!
    /*购物项代表的是当前书,并表示该书出现了几次*/    public class CartItem {            private Book book;        private int quantity;            //该购物项(书--不一定只有一本)的价钱应该等于书的数量*价格        private double price;                    //书的价钱*数量        public double getPrice() {            return book.getPrice() * 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 void setPrice(double price) {            this.price = price;        }    }
  • 购物车实体
    /*该类代表的是购物车*/    public class Cart {            //关键字是书籍的id,值是书        private Map<String, CartItem> bookMap = new LinkedHashMap<>();            //代表着购物车的总价        private double price;                //把购物项(用户传递进来的书籍)加入到购物车里边去,也应该是购物车的功能        public void addBook(Book book) {                //获取得到购物项            CartItem cartItem = bookMap.get(book.getId());                //判断购物车是否存在该购物项,如果不存在            if (cartItem == null) {                    //创建这个购物项对象                cartItem = new CartItem();                    //将用户传递过来的书籍作为购物项                cartItem.setBook(book);                    //把该购物项的数量设置为1                cartItem.setQuantity(1);                    //把购物项加入到购物车去                bookMap.put(book.getId(), cartItem);            } else {                    //如果存在该购物项,将购物项的数量+1                cartItem.setQuantity(cartItem.getQuantity() + 1);            }        }            //购物车的总价就是所有购物项的价格加起来        public double getPrice() {                double totalPrice = 0;                for (Map.Entry<String, CartItem> me : bookMap.entrySet()) {                    //得到每个购物项                CartItem cartItem = me.getValue();                    //将每个购物项的钱加起来,就是购物车的总价了!                totalPrice += cartItem.getPrice();            }                return totalPrice;        }                public Map<String, CartItem> getBookMap() {            return bookMap;        }            public void setBookMap(Map<String, CartItem> bookMap) {            this.bookMap = bookMap;        }                public void setPrice(double price) {            this.price = price;        }    }

③数据库

这里就直接用集合模拟数据库了,简单的domo而已。

    //既然是购物车案例,应该会有增删的操作,通过关键字查询书籍,所以使用LinkedHashMap集合    private static Map<String, Book> map = new LinkedHashMap<>();        static {        map.put("1",new Book("1", "java", "zhongfucheng", "好书", 99));        map.put("2",new Book("2", "javaweb", "ouzicheng", "不好的书", 44));        map.put("3",new Book("3", "ajax", "xiaoming", "一般般", 66));        map.put("4",new Book("4", "spring", "xiaohong", "还行", 77));    }    public static Map<String, Book> getAll() {        return map;    }

④开发dao

dao层应该至少提供获取所有的书籍根据关键字获取得到书籍

public class BookDao {    //获取存放着书籍的Map集合    public Map getAll() {        return BookDB.getAll();    }    //根据关键字获取某本书籍    public Book find(String id) {        return BookDB.getAll().get(id);    }}

⑤开发service

service层就是对DAO层的一个封装

    public class BusinessService {            BookDao bookDao = new BookDao();            /*列出所有的书*/        public Map getAll() {                return bookDao.getAll();        }        /*根据书的id获取书*/        public Book findBook(String id) {            return bookDao.find(id);        }            //...待会还有其他的功能再从这里补充!    }

⑥开发web

列出所有的书

开发提供JSP页面的Servlet

        //调用service层的方法,获取得到存放书籍的Map集合        BusinessService businessService = new BusinessService();        Map books = businessService.getAll();                //存放在request域对象中,交给jsp页面显示        request.setAttribute("books", books);                //跳转到jsp页面中        request.getRequestDispatcher("/WEB-INF/listBook.jsp").forward(request, response);

开发显示所有书籍的jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><head>    <title>显示所有的书籍</title></head><body><%--Servlet传递过来的是一个Map对象,要显示所有的书籍,就需要遍历Map集合(EL表达式和JSTL标签合用)--%><table border="1px">    <tr>        <td>书籍编号</td>        <td>名称</td>        <td>作者</td>        <td>详细信息</td>        <td>价格</td>    </tr>    <c:forEach items="${books}" var="me">        <tr>            <td>${me.key}</td>            <td>${me.value.name}</td>            <td>${me.value.author}</td>            <td>${me.value.description}</td>            <td>${me.value.price}</td>        </tr>    </c:forEach></table></body></html>

购买操作

作为购物车的案例,怎么能没有购买的操作呢?于是乎就增加购买的操作

购物车【JavaWeb小项目、简单版】

开发处理购买的Servlet

        //获取得到传递过来的id        String id = request.getParameter("bookid");        //把用户想要买的书放到购物车上        //用户不单单只有一个,要让购物车上只为当前的用户服务,就需要用到会话跟踪技术了        Cart cart = (Cart) request.getSession().getAttribute("cart");        //如果当前用户还没有点击过购买的商品,那么是用户的购物车是空的        if (cart == null) {            cart = new Cart();            request.getSession().setAttribute("cart", cart);        }        //调用BussinessService的方法,实现购买功能!        BusinessService businessService = new BusinessService();        businessService.buyBook(id, cart);        //跳转到购物车显示的页面上        request.getRequestDispatcher("/listCart.jsp").forward(request, response);
  • 在我们前面开发BusinessService时,是没有buyBook()这个方法的!下面更新了BusinessService的代码
    /*    * 在购买书籍的时候,我们发现需要将书籍添加到购物车上    * 如果我们直接在Servlet上使用Cart实体对象的addBook()和BookDao对象的find()方法,是可以完成功能的    *     * 但是,这样web层的程序就跟Dao层的耦合了,为了代码性的健壮性和解耦,我们在BusinessService中对他俩进行封装    *     * 于是有了buyBook()这个方法!    * */        /*把用户想买的书籍添加到当前用户的购物车上*/    public void buyBook(String id, Cart cart) {        Book book = bookDao.find(id);        cart.addBook(book);    }

购物车的页面

  • 初步把购物项的信息显示出来
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    <html>    <head>        <title>购物车显示页面</title>    </head>    <body>    <h1>购物车显示页面</h1>        <%--empty函数是判断集合中有没有元素--%>    <%--如果购物车是没有任何购物项的--%>    <c:if test="${empty(cart.bookMap)}">        <h1>您还没有购买过任何的书籍呀!</h1>    </c:if>        <%--如果购物车有购物项,就应该把购物项的信息显示给用户--%>    <c:if test="${!empty(cart.bookMap)}">            <table border="1px">            <tr>                <td>书籍编号</td>                <td>名称</td>                <td>数量</td>                <td>小计</td>                <td>操作</td>            </tr>            <c:forEach items="${cart.bookMap}" var="me">                <tr>                    <td>${me.key}</td>                    <td>${me.value.book.name}</td>                    <td>${me.value.quantity}</td>                    <td>${me.value.price}</td>                    <td><a href="#">删除</a></td>                </tr>            </c:forEach>            <tr>                <td colspan="2"><a href="#">清空购物车</a></td>                    <td colspan="2">合计:</td>                <td>${cart.price}</td>            </tr>            </table>        </c:if>            </table>        </body>    </html>
  • 效果是这样子的:

购物车【JavaWeb小项目、简单版】


删除购物车商品

购物车【JavaWeb小项目、简单版】

想要删除购物车中的商品,也很简单,把删除操作挂在超链接上,超链接指向DeleteCartServlet,并将想要删除的书本的id带过去(不将id带过去,服务器哪知道你要删除的是哪个)

    <td><a href="${pageContext.request.contextPath}/DeleteCartBook?bookid=${me.key}">删除</a></td>

开发DeleteCartBook的Servlet

        //获取得到用户想要删除哪个书本的id        String id = request.getParameter("bookid");        //获取该用户相对应的购物车对象        Cart cart = (Cart) request.getSession().getAttribute("cart");        try {            //删除购物车的商品,也应该是在BusinessService中有的功能,于是乎又回到BusinessService中写代码            BusinessService businessService = new BusinessService();            businessService.deleteBook(id, cart);            //删除购物车的商品后,也应该直接跳转回去购物车的显示页面中            request.getRequestDispatcher("/WEB-INF/listCart.jsp").forward(request, response);        } catch (CartNotFoundException e) {            request.setAttribute("message", "购物车空了!");            request.getRequestDispatcher("/message.jsp").forward(request, response);        } catch (Exception e) {            e.printStackTrace();            request.setAttribute("message", "删除中出现了异常~待会再试试呗!");            request.getRequestDispatcher("/message.jsp").forward(request, response);        }
  • BusinessService又多了一个功能
    /*用户要在购物车中删除某个购物项*/    public void deleteBook(String id, Cart cart) throws CartNotFoundException {        //如果用户是直接访问DeleteCartBook的Servlet的,在session中是没有cart这个属性的!        //告诉用户购物车是空的        if (cart == null) {            throw new CartNotFoundException("购物车为空");        }        //把购物项移除出去集合就行了!        cart.getBookMap().remove(id);    }

效果:

购物车【JavaWeb小项目、简单版】

多本一起购买

从上面的gif我们就可以发现,如果我重复买一本书,需要一本一本地点!这样会非常麻烦!

我们要怎么实现:用户想要买多少本,购物车的数量就修改为多少本呢

在购物车上,数量的值改成是输入框

    <td><input type="text" name="quantity" value="${me.value.quantity}"></td>

效果:
购物车【JavaWeb小项目、简单版】

好的,现在我们已经能够把数量随自己想要多少本,就改成是多少了。现在主要的问题就是,怎么在改的同时,数据也及时地更新?

写javascript代码,让输入框的信息提交给服务器

我们写javascript的代码,监控着输入框的变动,如果有变动,就响应事件,将变动的数据传递给服务器,更新数据!

    <script type="text/javascript">        /*        * @input 将输入框本身填入(这样可以获取得到输入框的值)        * @id   将书本的id传递进来,告诉服务器是修改哪一个购物项(书)        * @oldValue 原本的值,如果用户不想修改了,就修改为原本的值(下面会询问用户是否确定修改)        * */        function update(input,id,oldValue) {            //获取得到输入框的数据            var quantity = input.value;            //询问用户是否真的修改            var b = window.confirm("你确定修改吗?");            //如果确定修改,就跳转到修改的Servlet上            if(b) {                window.location.href = "${pageContext.request.contextPath}/UpdateQuantity?bookid=" + id + "&quantity=" + quantity + "";            }else {                //如果不确定修改,把输入框的数据改成是原来的                input.value = oldValue;            }        }    </script>

编写UpdateQuantity的Servlet

        //获取得到用户想要修改哪一本书的id和相对应的数量        String id = request.getParameter("bookid");        String quantity = request.getParameter("quantity");        //得到当前用户的购物车        Cart cart = (Cart) request.getSession().getAttribute("cart");        try {            //调用BusinessService的方法去修改对应的数据            BusinessService businessService = new BusinessService();            businessService.updateQuantity(id, cart, quantity);            //修改完再跳转回去购物车的页面中            request.getRequestDispatcher("/WEB-INF/listCart.jsp").forward(request, response);        } catch (CartNotFoundException e) {            e.printStackTrace();            request.setAttribute("message", "购物车是空的!");            request.getRequestDispatcher("message.jsp").forward(request, response);        }

BusinessService增添了updateQuantity()方法

    public void updateQuantity(String id, Cart cart, String quantity) throws CartNotFoundException {        //如果用户是直接访问DeleteCartBook的Servlet的,在session中是没有cart这个属性的!        //告诉用户购物车是空的        if (cart == null) {            throw new CartNotFoundException("购物车为空");        }        //通过书的id获取得到购物车的购物项,再修改购物项的数量即可!(因为书的id和获取购物项的关键字是一致的!)        cart.getBookMap().get(id).setQuantity(Integer.parseInt(quantity));    }
  • 效果如下gif

购物车【JavaWeb小项目、简单版】


清空购物车

清空购物车的做法和上面是类似的!也是首先通过javaScript代码询问用户是否要清空,如果要清空就跳转到相对应的Servlet中把购物车的数据清空了!

在清空购物车的链接上绑定事件

    <td colspan="2">        <a href="${pageContext.request.contextPath}/ClearCart" onclick=" return clearCart()" >清空购物车</a>    </td>

javaScript代码做逻辑判断

        function clearCart() {            var b = window.confirm("你确定要清空购物车吗?");            //如果用户确定,就跳转到相对应的Servlet上            if(b) {                return true;            }else {                return false;            }        }

编写ClearCart代码

        //得到用户相对应的购物车        Cart cart = (Cart) request.getSession().getAttribute("cart");        //调用相对应BusinessService的方法        BusinessService businessService = new BusinessService();        try {            //清空购物车【实际上就是清空购物车的Map集合中的元素】            businessService.clearCart(cart);            //返回给购物车显示页面            request.getRequestDispatcher("/WEB-INF/listCart.jsp").forward(request, response);        } catch (CartNotFoundException e) {            e.printStackTrace();            request.setAttribute("message", "购物车是空的!");            request.getRequestDispatcher("/message.jsp").forward(request, response);        }

在BusinessService中添加清空购物车功能

    public void clearCart(Cart cart) throws CartNotFoundException {        //如果用户是直接访问DeleteCartBook的Servlet的,在session中是没有cart这个属性的!        //告诉用户购物车是空的        if (cart == null) {            throw new CartNotFoundException("购物车为空");        }        //清空所有的购物项        cart.getBookMap().clear();    }
  • 效果:

购物车【JavaWeb小项目、简单版】


总结

  1. 购物车的应该是一个以id作为key,以购物项作为value的一个Map集合。这样设计的话,我们在显示商品的时候,就不会重复显示同一种类型的商品了。
  2. 购物项代表着该商品,并且应该给予购物项 数量和价钱的属性。购物项的价钱应该是数量*单价
  3. 购物车应该提供把商品添加到购物车的功能。当然啦,购物项代表着商品,所以首先要判断该购物车是否有同类的商品,如果有,直接在购物项的数量上+1即可的。如果没有,就设置该购物项的属性,并把购物项添加到购物车中
  4. 购物车的总价就是所有购物项的总价
  5. 无论是增删改查购物车的数据,其实就是操作这个集合

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章的同学,可以关注微信公众号:Java3y

更多的文章可往:文章的目录导航
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表