how2j.cn


工具版本兼容问题
从开发者的角度来看,购买行为 就是创建一条一条的订单项
而显示购物车,也就是把这些订单项显示在页面上。

在这个阶段,订单项都会保存在session中,直到最后生成订单的时候,才会把这些订单项保存在数据库中。


步骤 1 : SQL   
步骤 2 : OrderItem   
步骤 3 : ProductDAO   
步骤 4 : 购买商品   
步骤 5 : 显示购物车内容   
步骤 6 : 购买相同商品   
步骤 7 : 配置web.xml   
步骤 8 : 测试   
步骤 9 : 练习-删除订单项   
步骤 10 : 答案-删除订单项   
步骤 11 : 练习-加入购物车   
步骤 12 : 答案-加入购物车   

暂时不需要为OrderItem创建表,因为在这个环节OrderItem还是保存在Session中的
OrderItem使用属性Product类型的product,而非int类型的pid,因为在后续显示购物车的时候,可以很简单的通过el表达式就显示商品名称和价格了
${oi.product.name}
package bean; public class OrderItem { private int id; private Product product; private int num; public int getId() { return id; } public void setId(int id) { this.id = id; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } }
因为购买的时候,提交到服务器的是pid, 而OrderItem类的product属性是一个Product类型

所以ProductDAO需要根据id获取Product对象
package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import bean.Product; public class ProductDAO { public static void main(String[] args) { System.out.println(new ProductDAO().getProduct(1).getName()); } public Product getProduct(int id) { Product result = null; try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/cart?characterEncoding=UTF-8", "root", "admin"); String sql = "select * from product where id = ?"; PreparedStatement ps = c.prepareStatement(sql); ps.setInt(1, id); ResultSet rs = ps.executeQuery(); if (rs.next()) { result = new Product(); result.setId(id); String name = rs.getString(2); float price = rs.getFloat(3); result.setName(name); result.setPrice(price); } ps.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } public List<Product> ListProduct() { List<Product> products = new ArrayList<Product>(); try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/cart?characterEncoding=UTF-8", "root", "admin"); String sql = "select * from product order by id desc"; PreparedStatement ps = c.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { Product product = new Product(); int id = rs.getInt(1); String name = rs.getString(2); float price = rs.getFloat(3); product.setId(id); product.setName(name); product.setPrice(price); products.add(product); } ps.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return products; } }
购买行为本身就是创建一个OrderItem对象
在负责购买商品的OrderItemAddServlet 中,进行如下流程
1. 获取购买数量
2. 获取购买商品的id
3. 根据id获取商品对象
4. 创建一个新的OrderItem对象
5. 从session中取出一个List , 这个List里面存放陆续购买的商品。
如果是第一次从session中获取该List,那么它会是空的,需要创建一个ArrayList
6. 把新创建的OrderItem对象放入该List 中
7. 跳转到显示购物车的listOrderItem
package servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.OrderItem; import bean.Product; import dao.ProductDAO; public class OrderItemAddServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int num = Integer.parseInt(request.getParameter("num")); int pid = Integer.parseInt(request.getParameter("pid")); Product p = new ProductDAO().getProduct(pid); OrderItem oi = new OrderItem(); oi.setNum(num); oi.setProduct(p); List<OrderItem> ois = (List<OrderItem>) request.getSession().getAttribute("ois"); if (null == ois) { ois = new ArrayList<OrderItem>(); request.getSession().setAttribute("ois", ois); } ois.add(oi); response.sendRedirect("/listOrderItem"); } }
步骤 5 :

显示购物车内容

edit
显示购物车的OrderItemListServlet 其实什么也没做,因为数据已经在session准备好了,直接服务端跳转到listOrderItem.jsp

在listOrderItem.jsp中,从session中遍历出所有的OrderItem。 因为保存在OrderItem 上的是一个Product对象,所以很容易就可以通过EL表达式遍历出商品的名称和价格。
${oi.product.name}
${oi.product.price}
显示购物车内容
package servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Product; import dao.ProductDAO; public class OrderItemListServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("listOrderItem.jsp").forward(request, response); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <h1 align="center" >购物车</h1> <table align='center' border='1' cellspacing='0'> <tr> <td>商品名称</td> <td>单价</td> <td>数量</td> <td>小计</td> </tr> <c:forEach items="${ois}" var="oi" varStatus="st"> <tr> <td>${oi.product.name}</td> <td>${oi.product.price}</td> <td>${oi.num}</td> <td>${oi.product.price*oi.num}</td> </tr> </c:forEach> </table>
步骤 6 :

购买相同商品

edit
遍历session中所有的OrderItem

如果找到对应的product.id一样的条目,就调整其数量
如果没有找到,就新增加一条
package servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.OrderItem; import bean.Product; import dao.ProductDAO; public class OrderItemAddServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int num = Integer.parseInt(request.getParameter("num")); int pid = Integer.parseInt(request.getParameter("pid")); Product p = new ProductDAO().getProduct(pid); OrderItem oi = new OrderItem(); oi.setNum(num); oi.setProduct(p); List<OrderItem> ois = (List<OrderItem>) request.getSession().getAttribute("ois"); if (null == ois) { ois = new ArrayList<OrderItem>(); request.getSession().setAttribute("ois", ois); } boolean found = false; for (OrderItem orderItem : ois) { if (orderItem.getProduct().getId() == oi.getProduct().getId()) { orderItem.setNum(orderItem.getNum() + oi.getNum()); found = true; break; } } if (!found) ois.add(oi); response.sendRedirect("/listOrderItem"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>ProductListServlet</servlet-name> <servlet-class>servlet.ProductListServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ProductListServlet</servlet-name> <url-pattern>/listProduct</url-pattern> </servlet-mapping> <servlet> <servlet-name>UserLoginServlet</servlet-name> <servlet-class>servlet.UserLoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserLoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <servlet> <servlet-name>OrderItemAddServlet</servlet-name> <servlet-class>servlet.OrderItemAddServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>OrderItemAddServlet</servlet-name> <url-pattern>/addOrderItem</url-pattern> </servlet-mapping> <servlet> <servlet-name>OrderItemListServlet</servlet-name> <servlet-class>servlet.OrderItemListServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>OrderItemListServlet</servlet-name> <url-pattern>/listOrderItem</url-pattern> </servlet-mapping> </web-app>
从登陆页面开始,登陆后到产品显示页面,然后修改购买数量,最后点击购买

http://127.0.0.1/login.jsp
步骤 9 :

练习-删除订单项

edit Or  姿势不对,事倍功半! 点击查看做练习的正确姿势
在订单项后面增加一个删除按钮,表示可以删除这个订单项
步骤 10 :

答案-删除订单项

edit
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
查看本答案会花费3个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法
查看本答案会花费3个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法
账号未激活 账号未激活,功能受限。 请点击激活
答案在右上角的:cart_practise_delete.rar
步骤 11 :

练习-加入购物车

edit Or  姿势不对,事倍功半! 点击查看做练习的正确姿势
目前是购买,并且跳转到购物车页面。

修改为"加入购物车“,点击之后,"加入购物车“几个字变灰,不可点。 当前页面也不跳转。 通过ajax把这个数据提交到后台,加入购物车。

要准备一个显示购物车连接。
步骤 12 :

答案-加入购物车

edit
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
查看本答案会花费4个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法
查看本答案会花费4个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法
账号未激活 账号未激活,功能受限。 请点击激活
答案在右上角的:cart_practise_add_cart.rar


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2020-06-08 两个疑问
kira_

1.OrderItemAddServlet使用sendRedirect重定向到OrderItemListServlet上,而OrderItemListServlet什么也没有干,只是把Session里的参数通过getRequestDispatcher的方式跳转到jsp上,问题来了,为什么要多设置一个Servlet,难道不能直接跳转到jsp进行处理吗? 2.既然如此OrderItemAddServlet为什么使用sendRedirect重定向到第二个Servlet上?而第二个Servlet却是使用的是getRequestDispatcher呢?sendRedirect适用于不进行值传递的跳转需求,但是可以将参数放在session中通过setAttribute来传递参数这个我知道。所以只要是带参数的跳转,两者都可以?







回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2020-05-07 简单记录一下答案
学生new




跟着感觉做出来的,大部分效果实现了题目要求,前端学的不行,按钮按完之后变灰做不出来╮(╯▽╰)╭
package servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bean.OrderItem;

public class OrderItemDeleteServlet extends HttpServlet{

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		
		int id = Integer.parseInt(req.getParameter("id"));
		
			List<OrderItem> ois = new ArrayList<OrderItem>();
			ois = (List<OrderItem>) req.getSession().getAttribute("ois");
			for (OrderItem orderItem : ois) {
				if(orderItem.getProduct().getId()==id){
					ois.remove(orderItem);
					req.getSession().setAttribute("ois", ois);
					break;
				}
			}
		res.sendRedirect("listOrderItem");
	}
}


package servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import bean.OrderItem;
import bean.Product;
import dao.ProductDao;

public class OrderItemAddServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		
		int num = Integer.parseInt(req.getParameter("num"));
		int pid = Integer.parseInt(req.getParameter("pid"));
		
		Product p = new ProductDao().getProduct(pid);
		
		OrderItem oi = new OrderItem();
		oi.setId(0);
		oi.setNum(num);
		oi.setProduct(p);
		
		List<OrderItem> ois = (List<OrderItem>) req.getSession().getAttribute("ois");
		
		if(null == ois){
			ois = new ArrayList<OrderItem>();
			req.getSession().setAttribute("ois", ois);
		}
		
		//购买相同数量的产品
		boolean b = false;
		for (OrderItem orderItem : ois) {
			if(orderItem.getProduct().getId() == oi.getProduct().getId()){
				orderItem.setNum(orderItem.getNum()+oi.getNum());
				b=true;
				break;
			}
		}
		
		if(!b)
			ois.add(oi);
		
		req.getRequestDispatcher("listProduct").forward(req, res);
//		res.sendRedirect("listOrderItem");
	}
}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>


 
 <script type="text/javascript">
	$(function(){
		$("input.b").click(function(){
			$(this).removeAttr("disabled");
		$(this).attr({"disabled":true});
	});	
 });
</script>
 
<c:if test="${!empty user}">
<div align="center">
	当前用户:${user.name}
</div>
</c:if> 
 
<table align='center' border='1' cellspacing='0'>
    <tr>
        <td>id</td>
        <td>名称</td>
        <td>价格</td>
        <td>加入购物车</td>
    </tr>
    <c:forEach items="${list}" var="product" varStatus="st">
        <tr>
            <td>${product.id}</td>
            <td>${product.name}</td>
            <td>${product.price}</td>
            <td>
             
           <form action="addOrderItem" method="post"> 
            	数量<input type="text" value="1" name="num" >
            	<input type="hidden" name="pid" value="${product.id}">
            	<input type="submit" value="加入购物车" class="b"> 
             </form> 
            </td>
 
        </tr>
    </c:forEach>
    <tr>
    	<td colspan="4" align="right" ><a href="listOrderItem" style="text-decoration:none">进入购物车</a></td>
    </tr>
</table>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix='fmt' %>  

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">购物车</h1>

<table align="center" border="1" cellspacing="0">
<tr>
	<td>商品名称</td>
        <td>单价</td>
        <td>数量</td>
        <td>小计</td>
        <td>删除</td>
</tr>
<c:forEach items="${ois}" var="oi" varStatus="vs">
<tr>
<td>${oi.product.name}</td>
<td><fmt:formatNumber type="number" value="${oi.product.price}" maxFractionDigits="2"/>
</td>
<td>${oi.num}</td>
<td><fmt:formatNumber type="number" value="${oi.num*oi.product.price}" maxFractionDigits="2"/></td>
<td><a href="deleteOrderItem?id=${oi.product.id}">删除</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>

							


1 个答案

tmy009
答案时间:2020-05-09
我咋感觉你这个不是通过AJAX实现的。。XMLHttpRequest都没看见
XMLHttpRequest



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2020-05-03 我拿站长的最后一题答案跑了一下,然后发现在listProduct.jsp页面点击查看购物车以后,跳出来的购物车页面什么也没有
2020-04-07 无法显示数据,数据库已打开
2019-09-03 疑问


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 27 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 J2EE-购物车-购物车模块 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 635924385
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图