建立程序开拓包

②设计实体

书本实体

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}

购物车与购物项实体

jspservlet购物车ajaxJavaWeb基本购物车案例修订版 Angular

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

/该类代表的是购物车/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>

购买操作

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

开拓处理购买的Servlet

//获取得到通报过来的idString 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>效果是这样子的:

删除购物车商品

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

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

开拓DeleteCartBook的Servlet

//获取得到用户想要删除哪个书本的idString 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我们就可以创造,如果我重复买一本书,须要一本一本地点!
这样会非常麻烦!

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

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

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

效果:

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

写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

清空购物车

清空购物车的做法和上面是类似的!
也是首先通过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();}效果:

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

原文地址:https://dwz.cn/eG1FelKP

作者:Java3y