购物车模块
购物车存储方式:
1)保存在session中;此次项目保存在session中
2)保存在cookie中;
3)保存在数据库中:
不同方式的优缺点:
1.Session(Memcached)方式
优点:购物车信息保存在服务端,可以保存1M 信息。
缺点:1)对于大型网站会占有过多的服务器内存资源,造成服务器压力过大。
2)Session保存的信息会在用户退出登录后丢失。用户下次登录,购物车中商品信息丢失,用户只能从新选择。
2.Cookie方式
优点:购物车信息存储在客户端,不占用服务器资源,基本可以到达持久化存储。
缺点:Cookie有大小的限制,不能超过4K,而且不够安全、不能对用户购买行为分析统计
如果是个人PC机,Cookie能很好的保存购物车信息.
但如果是公共办公环境,Cookie保存的信息基本就失效了(会被其他人购物车信息覆盖)。
对于大型的电子商务网站,需要对用户的购买行为进行分析,如果把购物车信息保存在Cookie中,则不能对用户购买行为分析统计。
3.数据库存储
优点:持久化存储,可以分析用户购买行为。
缺点: 网站速度变慢,成本和维护增加。
1创建相关类
购物车的结构:
CartItem:包含图书和数量
Cart:包含一个Map<String,CartItem>
dao:没有
service:没有
web.servlet:提供!CartServlet
修改登录方法,在用户登录成功后,马上在session中添加一辆车!!!
页面:/jsps/cart/list.jsp
它只有一个任务,就是遍历车!
车在session中,通过车可以得到所有的CartItem
${sessionScope.cart.cartItems}
2 添加购物车条目

3 清空条目

4 删除购物车条目

5 我的购物车
top.jsp中存在一个链接:我的购物车
我的购物车直接访问/jsps/cart/list.jsp,它会显示session中车的所有条目
domian:
/**
* 购物车类
* @author 一万年行不行
*
*/
public class Cart {
/*
* map创建:
* 1.创建Map存放条目,以书id做键<书id,条目>
* 2.创建LinkedHashMap,为了保证顺序
*/
private Map<String,CartItem> map = new LinkedHashMap<String, CartItem>();
/**
* 合计 (所有条目价钱小计之和)
* 使用BigDecimal类型:解决二进制运算误差问题
* @return
*/
public double getTotal() {
//使用BigDecimal类型
BigDecimal total = BigDecimal.valueOf(0);
//遍历每个条目
for (CartItem cartItem : map.values()) {
//得到每个条目价钱(得到BigDecimal类型)
BigDecimal subTatal = BigDecimal.valueOf(cartItem.getSubtotal());
//对每个条目进行加法求和
total = total.add(subTatal);
}
return total.doubleValue(); //转为double类型
}
/**
* 添加条目
* @param cartItem
*/
public void add(CartItem cartItem){
/*
* 1.判断map中是否含有被添加条目
* 2.有,进行条目合并(合并数量)
* 条目合并:
* 1.拿到原条目
* 2.条目数量合并 (原数量 + 新数量)
* 3.将合并后的条目放进map
* 3.没有,直接添加
*/
if(map.containsKey(cartItem.getBook().getBid())){
//1.拿到原条目
CartItem _cartItem = map.get(cartItem.getBook().getBid());
//2.条目数量合并 (原数量 + 新数量)
_cartItem.setCount(_cartItem.getCount() + cartItem.getCount());
//3.将合并后的条目放进map
map.put(cartItem.getBook().getBid(), _cartItem);
}else{
//直接存放
map.put(cartItem.getBook().getBid(),cartItem);
}
}
/**
* 删除指定条目
* @param bid
*/
public void delete(String bid){
map.remove(bid);
}
/**
* 清空条目
*/
public void clear(){
map.clear();
}
/**
* 我的购物车(获取所有条目)
* @return
*/
public Collection<CartItem> getCartItems(){
return map.values();
}
}
/**
* 购物条目
* @author 一万年行不行
*
*/
public class CartItem {
private Book book; //商品
private int count; //商品数量
/**
* 小计方法:处理二进制运算误差问题
* @return
*/
public double getSubtotal(){ //计算方法,没有对应成员
//将double转化为BigDecimal类型:解决二进制运算误差问题
BigDecimal _price = BigDecimal.valueOf(book.getPrice());
BigDecimal _count = BigDecimal.valueOf(count);
//计算价格(价钱*数量),并转回double类型
return _price.multiply(_count).doubleValue();
}
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;
}
}
servlet:
public class CartServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
/**
* 添加购物 条目
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 1.得到session中的车(只有登陆的用户才有车)
* 2.得到购买的图书和数量
* 3.创建条目(条目包含图书和数量属性),并对条目设置图书和购买数
* 4.添加条目到车中
*/
Cart cart = (Cart) request.getSession().getAttribute("cart");
//得到条目,先得到图书的id,通过id查询数据库,得到book
String bid = request.getParameter("bid");
Book book = new BookService().load(bid);
//得到用户购买数量
int count = Integer.parseInt(request.getParameter("count"));
//创建条目,并对条目设置图书和购买数
CartItem cartItem = new CartItem();
cartItem.setBook(book);
cartItem.setCount(count);
cart.add(cartItem);
return "f:/jsps/cart/list.jsp";
}
/**
* 删除购物条目
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String delete(HttpServletRe