предисловие
Чтобы закрепить режим разработки 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<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;
}
}
③База данных
Здесь мы напрямую используем коллекцию для имитации базы данных, всего лишь простой домо.
//既然是购物车案例,应该会有增删的操作,通过关键字查询书籍,所以使用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 должен обеспечить хотя быПолучить все книгиа такжеПолучить книги на основе ключевых слов
public class BookDao {
//获取存放着书籍的Map集合
public Map getAll() {
return BookDB.getAll();
}
//根据关键字获取某本书籍
public Book find(String id) {
return BookDB.getAll().get(id);
}
}
⑤Служба разработки#
Сервисный уровень является инкапсуляцией уровня DAO.
public class BusinessService {
BookDao bookDao = new BookDao();
/*列出所有的书*/
public Map getAll() {
return bookDao.getAll();
}
/*根据书的id获取书*/
public Book findBook(String id) {
return bookDao.find(id);
}
//...待会还有其他的功能再从这里补充!
}
⑥Разработка веб
список всех книг
Разрабатывайте сервлеты, обслуживающие страницы JSP.
//调用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>
действие покупки
Как в случае с корзиной покупок может не быть операции покупки?Поэтому операция увеличения покупки!
Разработайте сервлет, который обрабатывает покупки
//获取得到传递过来的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);
- Когда мы разработали ранее бизнессервис, нет покупки () этого метода! Следующий обновленный код бизнессервиса:
/*
* 在购买书籍的时候,我们发现需要将书籍添加到购物车上
* 如果我们直接在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
//获取得到用户想要删除哪个书本的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);
}
Эффект:
Купите несколько книг вместе
На гифке выше мы видим, чтоЕсли я покупаю книгу повторно, мне нужно место по одной! Это будет очень хлопотно!
Как мы достигаем:Сколько копий пользователь хочет купить, сколько копий в корзине??
В корзине значение количества изменяется на поле ввода.
<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
//获取得到用户想要修改哪一本书的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.Если вы хотите очистить его, перейдите к соответствующему сервлету, чтобы очистить данные корзины!
Привязать событие к ссылке на пустую корзину
<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();
}
Суммировать
- Это должна быть тележка с идентификатором в качестве ключа, чтобы делать покупки в качестве коллекции карты стоимости. Этот дизайн, мы демонстрируем товар вовремя, он не показывает такого же типа товаров.
- Товар для покупок представляет товар и должен иметь атрибуты количества и цены. Цена товара должна быть равна количеству * цена за единицу.
- В корзине должна быть предусмотрена возможность добавления товаров в корзину. Конечно, товары для покупок представляют собой продукты, поэтому сначала необходимо определить, есть ли в корзине похожие товары.Если они есть, вы можете напрямую добавить 1 к количеству товаров для покупок. Если нет, задайте свойства товара и добавьте товар в корзину.
- Общая стоимость корзины – это сумма всех покупок.
- Будь то добавление, удаление, изменение и проверка данных корзины, на самом деле она работает с этой коллекцией.
Если в статье есть ошибки, пожалуйста, исправьте меня и поделитесь друг с другом. Студенты, которые привыкли читать технические статьи в WeChat, могутОбратите внимание на публичный аккаунт WeChat: Java3y