购物车实现逻辑详解
想要实现这样的效果:
1、首先要定义其模型
2、分析页面操作
3、实现其功能函数(在fun包下新建)
Cart.java
/**
* 购物车
*
@author
Administrator
*
*/
Public
class
Cart {
private
int
totalCount
; //购书数量
private
float
totalPrice
; //购书总价
private
Map
map
=
new
HashMap<>();//定义一个集合来存放购物项
//得到书的数量,怎么得?→bookId
public
int
getTotalCount() {
int
totalCount=0;
for
(Integer bookId:
map
.keySet()){
totalCount+=
map
.get(bookId).getCount();
}
return
totalCount;
}
/*API:public Set keySet()返回此映射中所包含的键的 set 视图。
for(Integer bookId:map.keySet()) ,这里面定义了一个和map集合键同类型的变量bookId
map.keySet()表示当前map集合中的所有的键的一个视图
分解:map.get( bookid ).getCount();
map.get( bookid );→ 根据键获取值(CartItem)→(CartItem)对象调用getCount();
*/
//得到书的总价?怎么得→bookId
public
float
getTotalPrice() {
float
totalPrice=0;
for
(Integer bookId:
map
.keySet()){
totalPrice+=
map
.get(bookId).getItemPrice();
}
return
totalPrice;
}
public
Map getMap() {
return
map
;
}
public
void
setMap(Map map) {
this
.
map
= map;
}
@Override
public
String toString() {
return
"Cart [totalCount="
+
totalCount
+
", totalPrice="
+
totalPrice
+
", map="
+
map
+
"]"
;
}
}
CartItem.java文件
/**
* 购物项类
*
@author
Administrator
*
*/
public
class
CartItem {
private
Book
book
; //图书
private
int
count
; //当前购物项的图书数量
public
CartItem() {
super
();
}
public
CartItem(Book book,
int
count) {
super
();
this
.
book
= book;
this
.
count
= count;
}
public
Book getBook() {
return
book
;
}
public
void
setBook(Book book) {
this
.
book
= book;
}
public
int
getCount() {
return
count
;
}
public
void
setCount(
int
count) {
this
.
count
= count;
}
// 得到小计
public
float
getItemPrice() {
return
book
.getPrice() *
count
;
}
@Override
public
String toString() {
return
"CartItem [book="
+
book
+
", count="
+
count
+
"]"
;
}
}
4、编写逻辑处理类CartServlet
大体思路:
①接收请求参数
②处理请求(谁来处理请求)
③转发请求
先定义好CartServlet然后依次写出待实现的空方法
public
class
CartServlet
extends
BaseServlet {
private
static
final
long
serialVersionUID
= 1L;
CartService
cartService
=
new
CartServiceImpl();
BookService
bookService
=
new
BookServiceImpl();
protected
void
add (HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
System.
out
.println(
"add...."
);
String bookid = request.getParameter(
"bookid"
);
Book book =
bookService
.getBookById(bookid);
Cart cart = WebUtils. getCart (request);
cartService
.add(book, cart);
WebUtils. myForward (request, response,
"/client/BookClientServlet?method=getPageInCondition"
);
}
protected
void
delete(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
System.
out
.println(
"delete..."
);
String bookid = request.getParameter(
"bookid"
);
Cart cart = WebUtils. getCart (request);
cartService
.deleteItem(Integer. parseInt (bookid), cart);
WebUtils. myForward (request, response,
"/client/book/cart.jsp"
);
}
protected
void
update(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
System.
out
.println(
"update...."
);
String count = request.getParameter(
"count"
);
String bookId = request.getParameter(
"bookId"
);
cartService
.updateCount(Integer. parseInt (bookId),
Integer. parseInt (count), WebUtils. getCart (request));
WebUtils. myForward (request, response,
"/client/book/cart.jsp"
);
}
protected
void
clear(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
System.
out
.println(
"clear....."
);
cartService
.clear(WebUtils. getCart (request));
WebUtils. myForward (request, response,
"/client/book/cart.jsp"
);
}
}
5、编写业务处理类接口
/**
* 处理购物车相关业务的接口
*
@author
Administrator
*
*/
public
interface
CartService {
//向购物车中添加书,书→book 购物车→cart
public
void
add(Book book ,Cart cart);
//删除一个购物项 ,在购物车中找到要删除的购物项的bookId
public
void
deleteItem(Integer BookId,Cart cart);
//更新购物车中书的数量
public
void
updateCount(
int
BookId,
int
count,Cart cart);
//清空购物车
public
void
clear(Cart cart);
}
6、编写业务处理接口的实现类
/**
* 处理购物车相关业务的实现类
*
@author
Administrator
*
*/
public
class
CartServiceImpl
implements
CartService {
/**
* 包含购物车中有书和没有书两种情况
*/
@Override
public
void
add(Book book, Cart cart) {
Integer bookId = book.getBookId();
CartItem cartItem = cart.getMap().get(bookId);
if
(cartItem==
null
){
//如果购物车为空的话
cartItem =
new
CartItem(book,1);
//创建一个购物项
cart.getMap().put(bookId, cartItem);
}
else
{
// 不为空的话
cartItem.setCount(cartItem.getCount()+1);
}
}
@Override
public
void
deleteItem(Integer BookId, Cart cart) {
cart.getMap().remove(BookId);
}
@Override
public
void
updateCount(
int
BookId,
int
count, Cart cart) {
cart.getMap().get(BookId).setCount(count);
}
@Override
public
void
clear (Cart cart) {
cart.getMap().clear();
}
}
6、页面访问(bookList.jsp)
数据来源:
bookid=
${book.bookId}
&bookName=
${book.bookName}
以上来自于:
<
li
>
书名:
<
a
href
=
"client/
BookClientServlet?method=getBook
★返回的是一个book对象,EL表达式可以获取book对象里面的属性.比如${book.bookId}
分析页面:
★页面上会显示三种状态:
●当没有书的时候:显示→购物车中暂时还没有一本书
●当点击其他分类的时候:显示→您的购物车中有1本书, 查看购物车
●当添加一本书的时候:显示→将 android 添加到了购物车, 购物车中有1本书, 查看购物车
如何实现呢??
< tr >
< td class = "centerTd" colspan = "2" >
< c:choose >
< c:when test = " ${ empty CART || empty CART.map} " >
购物车中暂时还没有一本书
c:when >
< c:when test = " ${ empty param.bookName} " >
您的购物车中有${CART.totalCount}本书, < a href = "client/book/cart.jsp?1=1" > 查看购物车 a >
c:when >
< c:otherwise >
将 < font color = "red" > ${param.bookName } font > 添加到了购物车, 购物车中有${CART.totalCount}本书,
< a href = "client/book/cart.jsp?1=1" > 查看购物车 a >
c:otherwise >
c:choose >
td >
tr
>
★详细解答页面显示的三种状态★
◆判断购物车为空和判断购物车集合为空有什么区别?
" ${empty CART || empty CART.map } " >
解答:这是两种情况,要分别写上
◆第二个和第三个条件类似都是查看购物车有几本书,那么如何区分呢?
解:区分标准就是看有没有点击链接(图书信息中的“加入购物车”)
◇那么,点没点击链接到底有什么区别嗯?
解:看第二个条件有一个显示效果,将 android 添加到了购物车 , 购物车中有 1 本书, 查看购物车
◇那么,如何动态的显示添加的书名呢?
解:★妙招:将
该链接的后面加上 &bookName= ${book.bookName} ,也即是:
好处:只要点击该链接就会携带该参数,既可以用以显示书名,还可以用于标识到底该执行哪个条件(第二个、第三个)
如果不加的话:会报一个路径错误 /BookStore/client/book/cart.jsp&cateId=&minPrice=&maxPrice=
设想:要让所有的连接至少携带一个参数,这样才能保证是一个正确的路径
解:设置一个没有用的参数,此时请求地址发送变化
http://localhost:8989/BookStore/client/book/cart.jsp?1=1&cateId=&minPrice=&maxPrice=
这个时候就能正常访问了
◇那么,如何理解 ${CART.totalCount} ?
我的理解: CART 是存在于 session 中的代表 Cart 的对象,因此可以调用 getTotalCount() 方法,在 EL 表达式中要将 T 转为小写
◆
点击:加入购物车 后 ···
<
li
><
a
href
=
"client/CartServlet?method=add&bookid=
${book.bookId}
&bookName=
${book.bookName}
"
>
加入购物车
a
>
li
>
◇分析: ${
empty
CART ||
empty
CART.map}
→数据来源于session,那么session中是什么时候设置进去呢?
在webUtils.java 中
/**
* 从请求的session中获取购物车对象
*
@param
request
*
@return
*/
public
static
Cart getCart(HttpServletRequest request) {
HttpSession session = request.getSession();
//从session中获取cart对象,不一定有,当为空的时候在创建
Cart cart = (Cart) session.getAttribute(
"CART"
);
if
(cart==
null
){
//如果获取不到就新 创建
cart =
new
Cart();
//新建一个购物车
session.setAttribute(
"CART"
,cart);
//将购物车设置进session中
}
return
cart;
}
什么时候用它的呢?
◇CartServlet中
protected
void
add(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
System.
out
.println(
"add...."
);
String bookid = request.getParameter(
"bookid"
);
Book book =
bookService
.getBookById(bookid);
Cart cart = WebUtils. getCart (request);//从session中获取购物车对象
cartService
.add(book, cart); //将书添加到购物车中国
WebUtils. myForward (request, response,
"/client/BookClientServlet?method=getPageInCondition"
);
}
7、显示页面Cart.jsp
◇点击 →
将
android
添加到了购物车, 购物车中有1本书, 查看购物车 →Cart.jsp
◆进入我的购物车之后有两种可能:购物车中有书、没有书
◇没有书:则显示没有书并跳转到购书页面(需要经过
BookClientServlet
)
<
c:when
test
=
"
${
empty
CART ||
empty
CART.map}
"
>
购物车中没有一本书, 立即去
<
a
href
=
"client/BookClientServlet?method=getPageInCondition"
>
购物
a
>
c:when
>
◇有书则显示列表
< body >
< center >
< h2 > 我的购物车 h2 >
< c:choose >
< c:when test = "${empty CART || empty CART.map}" >
购物车中没有一本书, 立即去< a href = "client/BookClientServlet?method=getPageInCondition" > 购物 a >
c:when >
< c:otherwise >
< table border = "1" cellpadding = "10" cellspacing = "0" >
< tr >
< td > 书名 td >
< td > 单价 td >
< td > 数量 td >
< td > 小计 td >
< td > 操作 td >
tr >
< c:forEach items = "${CART.map}" var = "entry" >
< tr >
< td > ${entry.value.book.bookName} td >
< td > ${entry.value.book.price} td >
< td >
< button class = "decrease" ${entry.value.count < =1 ? ' disabled ="false" ' : ' '} > - button >
< input id = "${entry.key}" class = "count" type = "text" value = "${entry.value.count}" style = "width: 30px;" />
< button class = "increase" > + button >
td >
< td > ${entry.value.itemPrice} td >
< td > < a class = "delete" href = "client/CartServlet?method=delete&bookid=${entry.key}" > 删除 a > td >
tr >
c:forEach >
< tr >
< td > < a id = "clear" href = "client/CartServlet?method=clear" > 清空购物车 a > td >
< td > < a
href = "client/BookClientServlet?method=getPageInCondition" > 继续购物 a > td >
< td > 共${CART.totalCount}本书 td >
< td > 总价:${CART.totalPrice}元 td >
< td > < a href = "#" > 去结算 a > td >
tr >
table >
c:otherwise >
c:choose >
center >
body >
8、清空购物车
点击:
< td>< a id =
"clear"
href =
"client/CartServlet?method=clear"
>
清空购物车
a> td >
进入
CartServlet
protected
void
clear(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
System.
out
.println(
"clear...."
);
cartService
.clear(WebUtils. getCart (request));
WebUtils. myForward (request, response,
"/client/book/cart.jsp"
);
}
9、 给所有删除链接添加点击事件
<
script
type
=
"text/javascript"
>
$(
function
(){
//给所有删除链接添加点击事件
$(
".delete"
).click(
function
(){
if
(!window.confirm(
"你确认删除吗?"
)) {
return
false
;
//不让链接提交请求
}
});
});
script
>
10、 给所有显示书的数量的输入框添加失去焦点的事件
就是这个:
$(
".count"
).blur(
function
(){
//得到输入框的值
var
count =
this
.value;
if
(isNaN(count)) {
count = 1;
}
count = count*1;
//转为number类型
if
(count<=0) {
count = 1;
}
//书的id
var
bookId =
this
.id;
//请求
window.location.href =
"${pageContext.request.contextPath}/client/CartServlet?method=update&count="
+count+
"&bookId="
+bookId;
});
11、 给+ 添加点击事件
$(
".increase"
).click(
function
(){
//得到数量
var
$countEle = $(
this
).parent().find(
"input"
);
var
count = $countEle.val();
//链式调用
count = count*1+1;
alert(count);
//书的id
var
bookId = $countEle.attr(
"id"
);
//请求
window.location.href =
"${pageContext.request.contextPath}/client/CartServlet?method=update&count="
+count+
"&bookId="
+bookId;
});
12、 给- 添加点击事件
$(
".decrease"
).click(
function
(){
//得到数量
var
$countEle = $(
this
).parent().find(
"input"
);
var
count = $countEle.val();
//链式调用
count = count*1-1;
alert(count);
//书的id
var
bookId = $countEle.attr(
"id"
);
//请求
window.location.href =
"${pageContext.request.contextPath}/client/CartServlet?method=update&count="
+count+
"&bookId="
+bookId;
});