购物车实现
- 需求分析与步骤分析
- 实体对象的封装
- 代码实现
1)需求分析与步骤分析
**需求分析:**在商品详情页面上,输入购买的数量,点击加入购物车,在购物车页面上展示里面所有的商品
涉及的实体有三个:购物车,购物车的每一项,商品
①购物车
内容:购物车项的map集合<商品id,商品车项>,总金额
操作:加入购物车,删除商品,清空购物车
②购物车项
内容:商品对象,购买数量,小计
③商品
步骤分析:
- 商品详情页面,输入购买数量,点击加入购物车:${path}/cart/add?pid=xxx&count=xxx
- 在CartServlet中的处理路径,添加add方法
先获取两个请求参数pid和count,通过pid查询商品product,封装为CartItem对象 - 获取购物车,调用addToCart
- 页面跳转
2)实体对象的封装
① 购物车项的实体 CartItem
public class CartItem implements Serializable{
private static final long serialVersionUID = 4208891955309023203L;
/**
* 商品--每一个列表项有一个商品
*/
private Product product;
/**
* 购买数量
*/
private Integer count;
/**
* 小计
*/
private Double subtotal;
public CartItem() {
super();
}
//小计由商品数量和单价计算得出 不需要提供
public CartItem(Product product, Integer count) {
super();
this.product = product;
this.count = count;
}
//小计由商品数量和单价计算得出
public Double getSubtotal() {
return count*product.getShopPrice();
}
//其余getter和setter方法略
}
② 购物车实体 Cart
购物车实体中不仅要定义购物车项的集合和总价,还要有可以添加购物车,删除购物车和清空购物车的功能。
public class Cart implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1921333786113588640L;
/**
* 每一个购物车包含多个购物车项--使用map集合封装
* 存放购物车项的集合 key:商品的id cartitem:购物车项
* 使用map集合便于删除单个购物车项
*/
private Map<String,CartItem> map=new LinkedHashMap<>();
/**
* 总价默认为0.0元
*/
private Double total=0.0;
/**
* 添加购物车项到购物车
* @param cartItem 需要添加的项
*/
public void addToCart(CartItem cartItem) {
//1、先判断购物车中有无该商品
//1.1 先获取该商品的id
String pid=cartItem.getProduct().getPid();
if(map.containsKey(pid)) {
//有--则在原来的基础上增加购买的数量
//设置购买数量 需要获取该商品之前的购买数量+现在的购买数量
CartItem oldCartItem=map.get(pid);
oldCartItem.setCount(oldCartItem.getCount()+cartItem.getCount());
}else {
//无--直接把购物车项添加到购物车中
map.put(pid, cartItem);
}
//2、添加完成之后修改金额--之前的金额+现在购买的金额
this.total+=cartItem.getSubtotal();
}
/**
* 根据id从购物车中删除购物车项
* @param pid 要移除的商品怕id
*/
public void removeFromCart(String pid) {
//1、从集合中删除
CartItem cartItem=map.remove(pid);
//2、修改金额
total-=cartItem.getSubtotal();
}
/**
* 清空购物车
*/
public void clearCart() {
//1、清空集合
map.clear();
//2、金额归零
total=0.0;
}
public Map<String, CartItem> getMap() {
return map;
}
public void setMap(Map<String, CartItem> map) {
this.map = map;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
}
3)代码实现
①修改product_info.jsp
添加加入购物车的表单:
② CartServlet处理增加路径
1. 处理路径
@WebServlet("/cart/*")
public class CartServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 5586846006359868083L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到URI
String uri=request.getRequestURI();
//处理各个方法抛出的异常
try {
if(uri.endsWith("/add")) {
add(request,response);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//抛出自定义异常
throw new MyException();
}
}
}
2. 编写一个获取购物车的方法
购物车信息是存在session中的,从session获取一个购物车,如果有直接返回,如果没有则新建一个购物车加入到session中
/**
* 获取一个购物车的方法
* @return
*/
public Cart getCart(HttpServletRequest request) {
//购物车保存在session中
Cart cart=(Cart) request.getSession().getAttribute("cart");
//判断购物车是否为空
if(cart==null) {
//创建一个cart加入到session中
cart=new Cart();
request.getSession().setAttribute("cart", cart);
}
return cart;
}
3. 加入购物车
/**
* 添加购物车
* @param request
* @param response
* @throws Exception
*/
private void add(HttpServletRequest request, HttpServletResponse response) throws Exception {
//1、获取pid和数量
String pid=request.getParameter("pid");
Integer count=Integer.parseInt(request.getParameter("count"));
//2、通过pid获取调用ProductService得到Product
Product product=new ProductServiceImpl().getById(pid);
//3、封装为CartItem
CartItem cartItem=new CartItem(product, count);
//4、添加到购物车
Cart cart=getCart(request);
cart.addToCart(cartItem);
//5、重定向
response.sendRedirect(request.getContextPath()+"/jsp/cart.jsp");
}
4. cart.jsp上展示数据
在jsp上使用c标签遍历map不方便,我们在Cart实体类中提供一个getItem方法返回一个map中的value–列表项的集合,然后遍历该列表项即可
/**
* 获取所有的购物车项
* @return 购物车项的集合
*/
public Collection<CartItem> getItems() {
return map.values();
}
cart.jsp中展示数据