资讯专栏INFORMATION COLUMN

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

ninefive / 618人阅读

摘要:购物项代表着该商品,并且应该给予购物项数量和价钱的属性。当然啦,购物项代表着商品,所以首先要判断该购物车是否有同类的商品,如果有,直接在购物项的数量上即可的。

前言
为了巩固MVC的开发模式,下面就写一个购物车的小案例..
①构建开发环境 导入需要用到的开发包

建立程序开发包

②设计实体 书籍实体
    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 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 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 me : bookMap.entrySet()) {
    
                //得到每个购物项
                CartItem cartItem = me.getValue();
    
                //将每个购物项的钱加起来,就是购物车的总价了!
                totalPrice += cartItem.getPrice();
            }
    
            return totalPrice;
        }
    
    
        public Map getBookMap() {
            return bookMap;
        }
    
        public void setBookMap(Map bookMap) {
            this.bookMap = bookMap;
        }
    
    
        public void setPrice(double price) {
            this.price = price;
        }
    }

③数据库

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

    //既然是购物车案例,应该会有增删的操作,通过关键字查询书籍,所以使用LinkedHashMap集合
    private static Map 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 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" %>


    显示所有的书籍



<%--Servlet传递过来的是一个Map对象,要显示所有的书籍,就需要遍历Map集合(EL表达式和JSTL标签合用)--%>

        
书籍编号 名称 作者 详细信息 价格
${me.key} ${me.value.name} ${me.value.author} ${me.value.description} ${me.value.price}
购买操作

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

开发处理购买的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" %>
    
    
        购物车显示页面
    
    
    

购物车显示页面

<%--empty函数是判断集合中有没有元素--%> <%--如果购物车是没有任何购物项的--%>

您还没有购买过任何的书籍呀!

<%--如果购物车有购物项,就应该把购物项的信息显示给用户--%>
书籍编号 名称 数量 小计 操作
${me.key} ${me.value.book.name} ${me.value.quantity} ${me.value.price} 删除
清空购物车 合计: ${cart.price}

效果是这样子的:

删除购物车商品

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

    删除
开发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);
    }

效果:

多本一起购买

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

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

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

效果:

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

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

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


    
编写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

清空购物车

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

在清空购物车的链接上绑定事件
    
        清空购物车
    
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();


    }

效果:

总结

购物车的应该是一个以id作为key,以购物项作为value的一个Map集合。这样设计的话,我们在显示商品的时候,就不会重复显示同一种类型的商品了。

购物项代表着该商品,并且应该给予购物项 数量和价钱的属性。购物项的价钱应该是数量*单价

购物车应该提供把商品添加到购物车的功能。当然啦,购物项代表着商品,所以首先要判断该购物车是否有同类的商品,如果有,直接在购物项的数量上+1即可的。如果没有,就设置该购物项的属性,并把购物项添加到购物车中

购物车的总价就是所有购物项的总价

无论是增删改查购物车的数据,其实就是操作这个集合

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68548.html

相关文章

  • Java3y文章目录导航

    摘要:前言由于写的文章已经是有点多了,为了自己和大家的检索方便,于是我就做了这么一个博客导航。 前言 由于写的文章已经是有点多了,为了自己和大家的检索方便,于是我就做了这么一个博客导航。 由于更新比较频繁,因此隔一段时间才会更新目录导航哦~想要获取最新原创的技术文章欢迎关注我的公众号:Java3y Java3y文章目录导航 Java基础 泛型就这么简单 注解就这么简单 Druid数据库连接池...

    KevinYan 评论0 收藏0
  • JavaWeb】图书管理系统【总结】

    摘要:存在则购物项的数量提供购买功能,参数是和。用户想要购买商品时,判断用户是否登陆了,还要判断购物车是否存在购物车使用来保存,不存在则创建。得到未发货的全部订单和已发货的全部订单,其实就是检索出不同状态的全部订单。 感想 该项目是目前为止,我写过代码量最多的项目了.....虽然清楚是没有含金量的【跟着视频来写的】,但感觉自己也在进步中...... 写的过程中,出了不少的问题.....非常多...

    张率功 评论0 收藏0
  • JavaWEB开发01——HTML

    摘要:网站信息页面需求分析我们公司的需要一个对外宣传的网站介绍介绍公司的主要业务公司的发展历史公司的口号等等信息技术分析概述超文本标记语言超文本比普通文本功能更加强大可以添加各种样式标记语言通过一组标签来对内容进行描述关键字是由浏览器来解释执行静 1.网站信息页面 1.1需求分析: 我们公司的需要一个对外宣传的网站介绍,介绍公司的主要业务,公司的发展历史,公司的口号等等信息 1.2技术分析:...

    IntMain 评论0 收藏0
  • (原创)2021基于jsp、javaweb、ssm网上商城定制v2.2

    摘要:年月最新发布本人原创作品,用户前台系统管理员后台项目完整,无任何。 2021年10月最新发布 本人原创作品,用户前台、系统管理员后台项目完整,无任何bug。 每行代码都是本人自己写,我在每行代码上面都写有注释,不懂任何问题都可以咨询 开发工具:IDEA  服务器:Tomcat8.0  jdk...

    不知名网友 评论0 收藏0
  • JavaWEB开发02——CSS&JS

    摘要:今日目标使用完成网站首页的优化使用完成网站注册页面的优化使用完成简单的数据校验使用完成图片轮播效果教学目标了解的概念了解的引入方式了解的基本用法和常用的选择器了解的盒子模型,悬浮和定位了解的概念掌握的基本语法,数据类型,能够使用完成简单的页 今日目标 使用CSS完成网站首页的优化 使用CSS完成网站注册页面的优化 使用JS完成简单的数据校验 使用JS完成图片轮播效果 教学目标: 了解...

    MorePainMoreGain 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<