avatar

百脑科技商城项目

项目傻瓜式教程分析

GitHub地址:https://github.com/panyongkang/gitRepository/tree/master/EStore-master

使用泛型的优点

在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码重用率

问题:确认支付时,不能返回操作成功页面
报错:MySql Lock wait timeout exceeded该如何处理?

解决方案:

参考:https://ningyu1.github.io/site/post/75-mysql-lock-wait-timeout-exceeded/

首页header模块

/commons/header.jsp部分
如图展示:

点击”购物车”链接
1
2
3
4
5
6
<li role="presentation" >
<a href="computerServlet?method=forwardPage&page=cart&pageNo=${computerpage.pageNo }">
<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span>&nbsp;购物车&nbsp;
<span class="badge">${sessionScope.ShoppingCart.computerNumber }</span>
</a>
</li>

跳转forwardPage()方法:

ComputerServlet.java代码:

1
2
3
4
5
	//跳转页面
protected void forwardPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String page = request.getParameter("page");
request.getRequestDispatcher("/WEB-INF/pages/" + page + ".jsp").forward(request, response);
}

首先在page=cart的cart.jsp页面判断购物车是否为空:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<c:choose>

##如果商品不为空,则显示商品信息
<c:when test="${ !empty sessionScope.ShoppingCart.computers }">
<br><br>
<div class="container">
<div class="container">
<div class="alert alert-success tip-success" id="computerNumber">您的购物车中共有 <b>${sessionScope.ShoppingCart.computerNumber } </b>件商品
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<table class="table table-striped">
<tr>
<td class="col-md-6">商品名</td>
<td class="col-md-2 text-center">数量</td>
<td class="col-md-2 text-center">价格</td>
<td class="col-md-2 text-center">操作</td>
</tr>
<c:forEach items = "${sessionScope.ShoppingCart.items }" var = "item">


<tr>
<td class="col-md-6 ">
<img alt="${item.computer.id }" src="${item.computer.url }"/ style="width:180px;height:180px;">
${item.computer.brand } &nbsp; ${item.computer.model }
</td>
<td class="col-md-2 cartItem text-center" style="height:100px;line-height: 200px;">
<input class="cartItemNum" step="${item.quantity }" type="text" size="1" name="${item.computer.id }" value="${item.quantity }" style="width:50px;height:30px;"/>
</td>
<td class="col-md-2 text-center">¥ <b>${item.computer.price }</b></td>
<td class="col-md-2 text-center">
<a class="btn btn-danger delete" href="computerServlet?method=remove&pageNo=${param.pageNo }&id=${item.computer.id }">删除</a>
</td>
</tr>


</c:forEach>
</table>


<div id="totalMoney" style="font-weight:bold;">总金额:¥ ${sessionScope.ShoppingCart.totalMoney }</span>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-8"></div>
<div class="col-xs-12 col-md-4 text-right" style="padding-left:30px;">
<a href="computerServlet?method=getComputers&pageNo=${param.pageNo }" class="btn btn-default" role="button">继续购物</a>


<a href="computerServlet?method=clear" class="btn btn-danger" role="button">清空购物车</a>


<a href="computerServlet?method=forwardPage&page=cash" class="btn btn-primary" role="button">结账</a>
</div>

</div>


</div>




</div>

</c:when>
##如果商品为空,则跳转到空页面
<c:otherwise>
<jsp:forward page="/WEB-INF/pages/emptycart.jsp" />
</c:otherwise>
</c:choose>
在首页中点击“加入购物车”按钮

/Estore/WebContent/WEB-INF/pages/computers.jsp代码:

1
2
3
<a href="computerServlet?method=addToCart&pageNo=${computerpage.pageNo }&id=${computer.id}&model=${computer.model}&brand=${computer.brand}" class="btn btn-primary addToCart" role="button">
<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span>
加入购物车</a>

加入购物车后弹出的提示框:

1
2
3
4
5
6
7
8
9
10
11
12
<div class="container tips">
<c:if test="${param.model != null}">

<div class="alert alert-success tip-success">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<strong>成功!</strong>您已经将 <b>${param.brand } ${param.model} </b>加入到购物车中!
<b><a href="computerServlet?method=forwardPage&page=cart&pageNo=${computerpage.pageNo }">立即查看购物车</a></b>
</div>

</c:if>

</div>

ComputerServlet.java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//添加到购物车
protected void addToCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String idStr =request.getParameter(“id”);
Int id=-1;
Boolean flag=false;
try {
id = Integer.parseInt(idStr);
} catch (Exception e) {}

if(id > 0){
//获取购物车对象
ShoppingCart sc = EStoreWebUtils.getShoppingCart(request);
//调用 ComputerService 的 addToCart() 方法把商品放到购物车中
Flag=computerService.addToCart(id,sc);
}

If(flag){
//添加成功,直接调用getComputers()方法,返回原来页面
GetComputers(request,response);
Return;
}
Response.sendRedirect(request.getContextPath() + "/error-1.jsp");
}

EStoreWebUtils.java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//获取购物车对象
/**
* 获取购物车对象: 从 session 中获取, 若 session 中没有改对象.
* 则创建一个新的购物车对象, 放入到 session 中.
* 若有, 则直接返回.
* @param request
* @return
*/
public static ShoppingCart getShoppingCart(HttpServletRequest request){
HttpSession session=request.getSession();
ShoppingCart sc=(ShoppingCart) session.getAttribute(“ShoppingCart”);
If(sc==null){
Sc=new ShoppingCart();
Session.setAttribute(“ShoppingCart”,sc);
}
Return sc;
}

//调用 ComputerService 的 addToCart() 方法把商品放到购物车中
ComputerService.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 把商品加入购物车
* @param id
* @param sc
* @return
*/
public boolean addToCart(int id, ShoppingCart sc) {
// 一、根据id获取computer对象
Computer computer = computerDAO.getComputer(id);
//判断是否存在
if (computer != null) {
//二、存在就执行方法将商品加入购物车
sc.addComputer(computer);
return true;
}
return false;


}

步骤一涉及的代码:
ComputerDAO.java接口:

1
2
3
4
5
6
/**
* 根据 id 获取指定 Computer 对象
* @param id
* @return
*/
public abstract Computer getComputer(int id);

ComputerDAOImpl.java实现类,继承BaseDAO类,实现ComputerDAO接口:

1
2
3
4
5
6
7
8
@Override
public Computer getComputer(int id) {
// TODO Auto-generated method stub
String sql = "SELECT id,brand,model,price,publishingDate,"+
"salesAmount,storeNumber,Remark,Url FROM mycomputers WHERE id = ?";

return query(sql, id);
}

BaseDAO类又实现dao接口的query()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public T query(String sql, Object... args) {
Connection connection = null;
try {
// connection = ConnectionContext.getInstance().get();
connection = JDBCUtils.getConnection();
return queryRunner.query(connection, sql, new BeanHandler<>(clazz), args);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(connection);
}
return null;
}

Dao接口:

1
2
3
4
5
6
7
/**
* 执行单条记录的查询操作, 返回与记录对应的类的一个对象
* @param sql: 待执行的 SQL 语句
* @param args: 填充占位符的可变参数
* @return: 与记录对应的类的一个对象
*/
T query(String sql, Object ... args);

步骤二涉及的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ShoppingCart.java:
/**
* 向购物车中添加一件商品
* @param computer
*/
public void addComputer(Computer computer){
//1. 检查购物车中有没有该商品, 若有, 则使其数量 +1, 若没有,
//新创建其对应的 ShoppingCartItem, 并把其加入到Map的对象 computers 中
ShoppingCartItem sci=computers.get(computer.getId());
If(sci==null){
//若没有,新创建其对应的 ShoppingCartItem,
并把其加入到Map的对象 computers 中
Sci=new ShoppingCartItem(computer);
Computers.put(computer.getId(),sci);
}else{
//若有, 则使其数量 +1,
Sci.increment();
}

ShoppingCartItem.java:

1
2
3
4
5
6
7
private int quantity;//数量
/**
* 使商品数量 + 1
*/
public void increment(){
quantity++;
}
点击“我的账户”
1
<li><a href="{pageContext.request.contextPath}/computerServlet?method=getMyphone&pageNo=1&id=1">我的账号</a></li>

如图所示:

/Estore/WebContent/WEB-INF/pages/myphone.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<%@page import="org.apache.jasper.tagplugins.jstl.core.Param"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*"
pageEncoding="UTF-8"%>
<%
String jsUrl=request.getContextPath()+"/public/js/";
String cssUrl=request.getContextPath()+"/public/css/";
String imgUrl=request.getContextPath()+"/public/img/";
%>
<!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>我的账号 </title>
<link href="<%=cssUrl%>bootstrap.min.css" rel="stylesheet">

<link href="<%=cssUrl%>index.css" rel="stylesheet">

<script type="text/javascript" src="<%=jsUrl%>jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="<%=jsUrl%>bootstrap.min.js"></script>
<%@ include file="/commons/queryCondition.jsp" %>

</head>

<body>
<%@ include file="/commons/header.jsp"%>

<center>
<div class="thumbnail">
<img src="img/tx.jpg" style="width:200px;height:200px;"/>
</div>
<div class="caption">
<br><br>
<span>用户名:${user.username}</span>
<br><br>
<span>密码:${user.password}</span>
<br><br>
<span>用户账号: ${user.accountId}</span>
<br><br>
<span>当前时间:<%=new Date().toLocaleString() %></span>
<br><br>
<span>账号备注: 保密</span>
<br><br>

<a class="btn btn-primary btn-ms" href="computerServlet?method=getComputers" role="button">返回</a>
<a href="${pageContext.request.contextPath}/userServlet?method=quitUser" class="btn btn-primary btn-ms" role="button"> 退出</a>
</div>

</center>
<%@ include file="/commons/footer.jsp"%>
</body>
</html>

/Estore/src/com/xmut/estore/servlet/ComputerServlet.java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//我的账号
protected void getMyphone(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
String username=request.getParameter("username");
String idStr = request.getParameter("id");
int id = -1;
User user=null;

try {
id = Integer.parseInt(idStr);
} catch (NumberFormatException e) {}
if (id > 0) {
user=userService.getUserByUserName(username);
}
request.setAttribute("user", user);
request.getRequestDispatcher("/WEB-INF/pages/myphone.jsp").forward(request, response);
}

/Estore/src/com/xmut/estore/service/UserService.java

1
2
3
4
5
6
7
8
/**
* 通过用户名获取User对象
* @param username
* @return
*/
public User getUserByUserName(String username){
return userDAO.getUser(username);
}

/Estore/src/com/xmut/estore/dao/UserDAO.java

1
2
3
4
5
6
/**
* 根据用户名获取 User 对象
* @param username
* @return
*/
public abstract User getUser(String username);

/Estore/src/com/xmut/estore/dao/impl/UserDAOImpl.java

1
2
3
4
5
6
@Override
public User getUser(String username) {
String sql = "SELECT userId, username, accountId " +
"FROM userinfo WHERE username = ?";
return query(sql, username);
}

/Estore/src/com/xmut/estore/dao/impl/BaseDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
public T query(String sql, Object... args) {

Connection connection = null;

try {
// connection = ConnectionContext.getInstance().get();
connection = JDBCUtils.getConnection();
return queryRunner.query(connection, sql, new BeanHandler<>(clazz), args);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(connection);
}

return null;
}

/Estore/src/com/xmut/estore/db/JDBCUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//获取数据库连接
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw new DBException("数据库连接错误!");
}
}
//关闭数据库连接
public static void release(Connection connection) {
try {
if(connection != null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
throw new DBException("数据库连接错误!");
}
}

/Estore/src/com/xmut/estore/dao/Dao.java

1
2
3
4
5
6
7
/**
* 执行单条记录的查询操作, 返回与记录对应的类的一个对象
* @param sql: 待执行的 SQL 语句
* @param args: 填充占位符的可变参数
* @return: 与记录对应的类的一个对象
*/
T query(String sql, Object ... args);
返回和退出

//返回的方法
/Estore/src/com/xmut/estore/servlet/ComputerServlet.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected void getComputers(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pageNoStr = request.getParameter("pageNo");
String minPriceStr = request.getParameter("minPrice");//最低价格
String maxPriceStr = request.getParameter("maxPrice");//最高价格


int pageNo = 1;
int minPrice = 0;
int maxPrice = Integer.MAX_VALUE;

try {
pageNo = Integer.parseInt(pageNoStr);
} catch (NumberFormatException e) {}

try {
minPrice = Integer.parseInt(minPriceStr);
} catch (NumberFormatException e) {}

try {
maxPrice = Integer.parseInt(maxPriceStr);
} catch (NumberFormatException e) {}

CriteriaComputer criteriaComputer = new CriteriaComputer(minPrice, maxPrice, pageNo);
Page<Computer> page = computerService.getPage(criteriaComputer);

request.setAttribute("computerpage", page);
request.getRequestDispatcher("/WEB-INF/pages/computers.jsp").forward(request, response);
}

//退出的方法
/Estore/src/com/xmut/estore/servlet/UserServlet.java

1
2
3
4
5
6
7
8
9
10
11
 /**
* 用户退出
* @param request
* @param response
* @throws IOException
*/
public void quitUser(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 退出当前登陆
request.getSession().invalidate();
response.sendRedirect(request.getContextPath()+"/login.jsp");
}

首页body模块

/WEB-INF/pages/computers.jsp部分

价格查询


/Estore/WebContent/WEB-INF/pages/computers.jsp代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="container searchBox">
<form action="computerServlet?method=getComputers" method="post" class="form-inline">
<div class="form-group">
<div >
<label class="sr-only" for="exampleInputAmount">Amount (in dollars)</label>
<div class="input-group">
<div class="input-group-addon">从</div>
<input type="text" class="form-control col-xs-1" name="minPrice" placeholder="最低价格"/>
<div class="input-group-addon">到</div>
<input type="text" class="form-control col-xs-1" name="maxPrice" placeholder="最高价格"/>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary searchBtn "><span class="glyphicon glyphicon-search" aria-hidden="true"></span> 查询</button>
</form>
</div>

/Estore/src/com/xmut/estore/servlet/ComputerServlet.java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected void getComputers(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pageNoStr = request.getParameter("pageNo");
String minPriceStr = request.getParameter("minPrice");//最低价格
String maxPriceStr = request.getParameter("maxPrice");//最高价格


int pageNo = 1;
int minPrice = 0;
int maxPrice = Integer.MAX_VALUE;

try {
pageNo = Integer.parseInt(pageNoStr);
} catch (NumberFormatException e) {}

try {
minPrice = Integer.parseInt(minPriceStr);
} catch (NumberFormatException e) {}

try {
maxPrice = Integer.parseInt(maxPriceStr);
} catch (NumberFormatException e) {}

CriteriaComputer criteriaComputer = new CriteriaComputer(minPrice, maxPrice, pageNo);
Page<Computer> page = computerService.getPage(criteriaComputer);

request.setAttribute("computerpage", page);
request.getRequestDispatcher("/WEB-INF/pages/computers.jsp").forward(request, response);
}

/Estore/src/com/xmut/estore/web/CriteriaComputer.java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.xmut.estore.web;

public class CriteriaComputer {
//封装查询条件的CriteriaComputer类
private float minPrice = 0;
private float maxPrice = Integer.MAX_VALUE;
private int pageNo;

public CriteriaComputer(float minPrice, float maxPrice, int pageNo) {
super();
this.minPrice = minPrice;
this.maxPrice = maxPrice;
this.pageNo = pageNo;
}

public float getMinPrice() {
return minPrice;
}
public void setMinPrice(float minPrice) {
this.minPrice = minPrice;
}
public float getMaxPrice() {
return maxPrice;
}
public void setMaxPrice(float maxPrice) {
this.maxPrice = maxPrice;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}

}

/Estore/src/com/xmut/estore/service/ComputerService.java

1
2
3
public Page<Computer> getPage(CriteriaComputer cc){
return computerDAO.getPage(cc);
}

/Estore/src/com/xmut/estore/dao/ComputerDAO.java

1
2
3
4
5
6
/**
* 根据传入的 CriteriaComputer 对象返回对应的 Page 对象
* @param cc
* @return
*/
public abstract Page<Computer> getPage(CriteriaComputer cc);

/Estore/src/com/xmut/estore/dao/impl/ComputerDAOImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
//将请求条件封装成CriteriaComputer
@Override
public Page<Computer> getPage(CriteriaComputer cc) {
// TODO Auto-generated method stub
Page<Computer> page = new Page<>(cc.getPageNo());

page.setTotalItemNumber(getTotalComputerNumber(cc));
//校验pageNo的合法性
cc.setPageNo(page.getPageNo());
page.setList(getPageList(cc, 6));
return page;
}

/Estore/src/com/xmut/estore/web/Page.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class Page<T> {

//当前第几页
private int pageNo;

//当前页的 List
private List<T> list;

//每页显示多少条记录
private int pageSize = 6;

//共有多少条记录
private long totalItemNumber;

//构造器中需要对 pageNo 进行初始化
public Page(int pageNo) {
super();
this.pageNo = pageNo;
}

//校验页数是否合法
public int getPageNo() {
if(pageNo < 0)
pageNo = 1;

if(pageNo > getTotalPageNumber()){
pageNo = getTotalPageNumber();
}

return pageNo;
}

public int getPageSize() {
return pageSize;
}

public void setList(List<T> list) {
this.list = list;
}

public List<T> getList() {
return list;
}

//获取总页数
public int getTotalPageNumber(){

int totalPageNumber = (int)totalItemNumber / pageSize;

if(totalItemNumber % pageSize != 0){
totalPageNumber++;
}

return totalPageNumber;
}

public void setTotalItemNumber(long totalItemNumber) {
this.totalItemNumber = totalItemNumber;
}

public boolean isHasNext(){
if(getPageNo() < getTotalPageNumber()){
return true;
}

return false;
}

public boolean isHasPrev(){
if(getPageNo() > 1){
return true;
}

return false;
}

public int getPrevPage(){
if(isHasPrev()){
return getPageNo() - 1;
}

return getPageNo();
}

public int getNextPage(){
if(isHasNext()){
return getPageNo() + 1;
}

return getPageNo();
}
}
首页商品展示

分页模块展示

首页footer模块


/Estore/WebContent/commons/footer.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<hr width="80%" >
<div class="navbar navbar-default navbar-static-top" >
<footer class="footer" style="margin-top:10px;">
<div class="container">
<div id="back-to-top" href="#">
<span class="glyphicon glyphicon-triangle-top"></span>&nbsp;回到顶部
</div>
<p class="text-muted">&copy; 2019 百脑 科技 有限责任公司.

</p>

</div>
</footer>
</div>

购物车模块

模块分析

进入购物车后,首先判断商品是否为空,不为空则显示商品详情页,如果为空则跳转到空页面,此时就使用到c:标签判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String jsUrl=request.getContextPath()+"/public/js/";
String cssUrl=request.getContextPath()+"/public/css/";
String imgUrl=request.getContextPath()+"/public/img/";
%>
<!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>购物车</title>
<link href="<%=cssUrl%>bootstrap.min.css" rel="stylesheet">

<link href="<%=cssUrl%>index.css" rel="stylesheet">
<link href="<%=cssUrl%>cart.css" rel="stylesheet">
<script type="text/javascript" src="<%=jsUrl%>jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="<%=jsUrl%>bootstrap.min.js"></script>
<script type="text/javascript" src="<%=jsUrl%>cartValidate.js"></script>
<%@ include file="/commons/queryCondition.jsp" %>
</head>
<body>
<%@ include file="/commons/header.jsp"%>
<c:choose>

<c:when test="${ !empty sessionScope.ShoppingCart.computers }">
<br><br>
<div class="container">
<div class="container">
<div class="alert alert-success tip-success" id="computerNumber">您的购物车中共有 <b>${sessionScope.ShoppingCart.computerNumber } </b>件商品</div>
<table class="table table-striped">
<tr>
<td class="col-md-6">商品名</td>
<td class="col-md-2 text-center">数量</td>
<td class="col-md-2 text-center">价格</td>
<td class="col-md-2 text-center">操作</td>
</tr>
<c:forEach items = "${sessionScope.ShoppingCart.items }" var = "item">


<tr>
<td class="col-md-6 ">
<img alt="${item.computer.id }" src="${item.computer.url }"/ style="width:180px;height:180px;">
${item.computer.brand } &nbsp; ${item.computer.model }
</td>
<td class="col-md-2 cartItem text-center" style="height:100px;line-height: 200px;">
<input class="cartItemNum" step="${item.quantity }" type="text" size="1" name="${item.computer.id }" value="${item.quantity }" style="width:50px;height:30px;"/>
</td>
<td class="col-md-2 text-center">¥ <b>${item.computer.price }</b></td>
<td class="col-md-2 text-center">
<a class="btn btn-danger delete" href="computerServlet?method=remove&pageNo=${param.pageNo }&id=${item.computer.id }">删除</a>
</td>
</tr>


</c:forEach>
</table>


<div id="totalMoney" style="font-weight:bold;">总金额:¥ ${sessionScope.ShoppingCart.totalMoney }</span>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-8"></div>
<div class="col-xs-12 col-md-4 text-right" style="padding-left:30px;">
<a href="computerServlet?method=getComputers&pageNo=${param.pageNo }" class="btn btn-default" role="button">继续购物</a>


<a href="computerServlet?method=clear" class="btn btn-danger" role="button">清空购物车</a>


<a href="computerServlet?method=forwardPage&page=cash" class="btn btn-primary" role="button">结账</a>
</div>

</div>


</div>




</div>

</c:when>
<c:otherwise>
<jsp:forward page="/WEB-INF/pages/emptycart.jsp" />
</c:otherwise>
</c:choose>
<%@ include file="/commons/footer.jsp"%>
</body>
</html>
商品详情

消息提示框:

1
2
3
4
5
6
7
/Estore/WebContent/WEB-INF/pages/cart.jsp

<div class="alert alert-success tip-success" id="computerNumber">
您的购物车中共有 <b>${sessionScope.ShoppingCart.computerNumber } </b>件商品
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span></button>
</div>

循环商品表格:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/Estore/WebContent/WEB-INF/pages/cart.jsp

<table class="table table-striped">
<tr>
<td class="col-md-6">商品名</td>
<td class="col-md-2 text-center">数量</td>
<td class="col-md-2 text-center">价格</td>
<td class="col-md-2 text-center">操作</td>
</tr>
<c:forEach items = "${sessionScope.ShoppingCart.items }" var = "item">


<tr>
<td class="col-md-6 ">
<img alt="${item.computer.id }" src="${item.computer.url }" style="width:180px;height:180px;">
${item.computer.brand } &nbsp; ${item.computer.model }
</td>
<td class="col-md-2 cartItem text-center" style="height:100px;line-height: 200px;">
<input class="cartItemNum" step="${item.quantity }" type="text" size="1" name="${item.computer.id }" value="${item.quantity }" style="width:50px;height:30px;"/>
</td>
<td class="col-md-2 text-center">¥ <b>${item.computer.price }</b></td>
<td class="col-md-2 text-center">
<a class="btn btn-danger delete" href="computerServlet?method=remove&pageNo=${param.pageNo }&id=${item.computer.id }">删除</a>
</td>
</tr>


</c:forEach>
</table>

##修改数量使件数和总金额发生变化
/Estore/WebContent/public/js/cartValidate.js

$(function(){

//ajax 修改单个商品的数量:
//1. 获取页面中所有的 text, 并为其添加 onchange 响应函数. 弹出确认对话框: 确定要修改吗?
$(":text").change(function(){
var quantityVal = $.trim(this.value);

var flag = false;

var reg = /^\d+$/g;
var quantity = -1;
if(reg.test(quantityVal)){
quantity = parseInt(quantityVal);
if(quantity >= 0){
flag = true;
}
}

if(!flag){
alert("输入的数量不合法!");
$(this).val($(this).attr("step"));
return;
}

var $tr = $(this).parent().parent();
var title = $.trim($tr.find("td:first").text());

if(quantity == 0){
var flag2 = confirm("确定要删除" + title + "吗?");
if(flag2){
//得到了 a 节点
var $a = $tr.find("td:last").find("a");
//执行 a 节点的 onclick 响应函数.
$a[0].onclick();

return;
}
}

var flag = confirm("确定要修改" + title + "的数量吗?");

if(!flag){
$(this).val($(this).attr("class"));
return;
}
//2. 请求地址为: computerServlet
var url = "computerServlet";

//3. 请求参数为: method:updateItemQuantity, id:name属性值, quantity:val, time:new Date()
var idVal = $.trim(this.name);
var args = {"method":"updateItemQuantity", "id":idVal, "quantity":quantityVal, "time":new Date()};

//4. 在 updateItemQuantity 方法中, 获取 quanity, id, 再获取购物车对象, 调用 service 的方法做修改
//5. 传回 JSON 数据: computerNumber:xx, totalMoney

//6. 更新当前页面的 computerNumber 和 totalMoney
$.post(url, args, function(data){
var computerNumber = data.computerNumber;
var totalMoney = data.totalMoney;

$("#totalMoney").text("总金额:¥ " + totalMoney);
$("#computerNumber").text("您的购物车中共有" + computerNumber + "件商品");
},"JSON");

});

})

总金额:

1
2
3
4
/Estore/WebContent/WEB-INF/pages/cart.jsp

<div id="totalMoney" style="font-weight:bold;">总金额:¥${sessionScope.ShoppingCart.totalMoney }</span>
</div>
“删除”按钮
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/Estore/WebContent/WEB-INF/pages/cart.jsp

<td class="col-md-2 text-center">
<a class="btn btn-danger delete" href="computerServlet?method=remove&pageNo=${param.pageNo }&id=${item.computer.id }">删除</a>
</td>

/Estore/WebContent/public/js/cartValidate.js

$(function(){
$(".delete").click(function(){

var $tr = $(this).parent().parent();
var title = $.trim($tr.find("td:first").text());
var flag = confirm("确定要删除" + title + "吗?");

if(flag){
return true;
}else{
return false;
}


});

})

/Estore/src/com/xmut/estore/servlet/ComputerServlet.java

protected void remove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String idStr = request.getParameter("id");

int id = -1;
boolean flag = false;
try {
id = Integer.parseInt(idStr);
} catch (Exception e) {}

ShoppingCart sc = EStoreWebUtils.getShoppingCart(request);
computerService.removeItemFromShoppingCart(sc, id);

if(sc.isEmpty()){
request.getRequestDispatcher("/WEB-INF/pages/emptycart.jsp").forward(request, response);
return;
}

request.getRequestDispatcher("/WEB-INF/pages/cart.jsp").forward(request, response);

}

/Estore/src/com/xmut/estore/web/EStoreWebUtils.java
package com.xmut.estore.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.xmut.estore.domain.ShoppingCart;

public class EStoreWebUtils {
/**
* 获取购物车对象: 从 session 中获取, 若 session 中没有该对象.
* 则创建一个新的购物车对象, 放入到 session 中.
* 若有, 则直接返回.
* @param request
* @return
*/
public static ShoppingCart getShoppingCart(HttpServletRequest request){
HttpSession session = request.getSession();

ShoppingCart sc = (ShoppingCart) session.getAttribute("ShoppingCart");
if(sc == null){
sc = new ShoppingCart();
session.setAttribute("ShoppingCart", sc);
}

return sc;
}
}
/Estore/src/com/xmut/estore/service/ComputerService.java

public void removeItemFromShoppingCart(ShoppingCart sc, int id) {
sc.removeItem(id);
}

/Estore/src/com/xmut/estore/domain/ShoppingCart.java

/**
* 移除指定的购物项
* @param id
*/
public void removeItem(Integer id){
computers.remove(id);
}
继续购物

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-8"></div>
<div class="col-xs-12 col-md-4 text-right" style="padding-left:30px;"><a href="computerServlet?method=getComputers&pageNo=${param.pageNo }" class="btn btn-default" role="button">继续购物</a>
</div>
</div>
</div>

/Estore/src/com/xmut/estore/servlet/ComputerServlet.java

protected void getComputers(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pageNoStr = request.getParameter("pageNo");
String minPriceStr = request.getParameter("minPrice");//最低价格
String maxPriceStr = request.getParameter("maxPrice");//最高价格


int pageNo = 1;
int minPrice = 0;
int maxPrice = Integer.MAX_VALUE;

try {
pageNo = Integer.parseInt(pageNoStr);
} catch (NumberFormatException e) {}

try {
minPrice = Integer.parseInt(minPriceStr);
} catch (NumberFormatException e) {}

try {
maxPrice = Integer.parseInt(maxPriceStr);
} catch (NumberFormatException e) {}

CriteriaComputer criteriaComputer = new CriteriaComputer(minPrice, maxPrice, pageNo);
Page<Computer> page = computerService.getPage(criteriaComputer);

request.setAttribute("computerpage", page);
request.getRequestDispatcher("/WEB-INF/pages/computers.jsp").forward(request, response);
}

/Estore/src/com/xmut/estore/web/CriteriaComputer.java

//封装查询条件的CriteriaComputer类
private float minPrice = 0;
private float maxPrice = Integer.MAX_VALUE;
private int pageNo;

public CriteriaComputer(float minPrice, float maxPrice, int pageNo) {
super();
this.minPrice = minPrice;
this.maxPrice = maxPrice;
this.pageNo = pageNo;
}

public float getMinPrice() {
return minPrice;
}
public void setMinPrice(float minPrice) {
this.minPrice = minPrice;
}
public float getMaxPrice() {
return maxPrice;
}
public void setMaxPrice(float maxPrice) {
this.maxPrice = maxPrice;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}

/Estore/src/com/xmut/estore/service/ComputerService.java

public Page<Computer> getPage(CriteriaComputer cc){
return computerDAO.getPage(cc);
}

/Estore/src/com/xmut/estore/dao/ComputerDAO.java

/**
* 根据传入的 CriteriaComputer 对象返回对应的 Page 对象
* @param cc
* @return
*/
public abstract Page<Computer> getPage(CriteriaComputer cc);

/Estore/src/com/xmut/estore/dao/impl/ComputerDAOImpl.java

//将请求条件封装成CriteriaComputer
@Override
public Page<Computer> getPage(CriteriaComputer cc) {
// TODO Auto-generated method stub
Page<Computer> page = new Page<>(cc.getPageNo());

page.setTotalItemNumber(getTotalComputerNumber(cc));
//校验pageNo的合法性
cc.setPageNo(page.getPageNo());
page.setList(getPageList(cc, 6));
return page;
}
/Estore/src/com/xmut/estore/web/Page.java

package com.xmut.estore.web;

import java.util.List;

public class Page<T> {

//当前第几页
private int pageNo;

//当前页的 List
private List<T> list;

//每页显示多少条记录
private int pageSize = 6;

//共有多少条记录
private long totalItemNumber;

//构造器中需要对 pageNo 进行初始化
public Page(int pageNo) {
super();
this.pageNo = pageNo;
}

//校验页数是否合法
public int getPageNo() {
if(pageNo < 0)
pageNo = 1;

if(pageNo > getTotalPageNumber()){
pageNo = getTotalPageNumber();
}

return pageNo;
}

public int getPageSize() {
return pageSize;
}

public void setList(List<T> list) {
this.list = list;
}

public List<T> getList() {
return list;
}

//获取总页数
public int getTotalPageNumber(){

int totalPageNumber = (int)totalItemNumber / pageSize;

if(totalItemNumber % pageSize != 0){
totalPageNumber++;
}

return totalPageNumber;
}

public void setTotalItemNumber(long totalItemNumber) {
this.totalItemNumber = totalItemNumber;
}

public boolean isHasNext(){
if(getPageNo() < getTotalPageNumber()){
return true;
}

return false;
}

public boolean isHasPrev(){
if(getPageNo() > 1){
return true;
}

return false;
}

public int getPrevPage(){
if(isHasPrev()){
return getPageNo() - 1;
}

return getPageNo();
}

public int getNextPage(){
if(isHasNext()){
return getPageNo() + 1;
}

return getPageNo();
}
}
清空购物车

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-8"></div>
<div class="col-xs-12 col-md-4 text-right" style="padding-left:30px;"><a href="computerServlet?method=clear" class="btn btn-danger" role="button">清空购物车</a>
</div>
</div>
</div>

/Estore/src/com/xmut/estore/servlet/ComputerServlet.java

protected void clear(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

ShoppingCart sCart = EStoreWebUtils.getShoppingCart(request);
computerService.clearShoppingCart(sCart);
request.getRequestDispatcher("/WEB-INF/pages/emptycart.jsp").forward(request, response);
}

/Estore/src/com/xmut/estore/service/ComputerService.java

public void clearShoppingCart(ShoppingCart sc) {
// TODO Auto-generated method stub
sc.clear();
}

/Estore/src/com/xmut/estore/domain/ShoppingCart.java

/**
* 清空购物车
*/
public void clear(){
computers.clear();
}
结账

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="container">
<div class="row">
<div class="col-xs-6 col-md-8"></div>
<div class="col-xs-12 col-md-4 text-right" style="padding-left:30px;"><a href="computerServlet?method=forwardPage&page=cash" class="btn btn-primary" role="button">结账</a>
</div>
</div>
</div>

/Estore/src/com/xmut/estore/servlet/ComputerServlet.java

//跳转到结账页面
protected void forwardPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String page = request.getParameter("page");
request.getRequestDispatcher("/WEB-INF/pages/" + page + ".jsp").forward(request, response);
}

结账页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/Estore/WebContent/WEB-INF/pages/cash.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String jsUrl=request.getContextPath()+"/public/js/";
String cssUrl=request.getContextPath()+"/public/css/";
String imgUrl=request.getContextPath()+"/public/img/";
String flieUrl = request.getContextPath()+"/WEB-INF/pages/";
%>
<!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>结账</title>
<link href="<%=cssUrl%>bootstrap.min.css" rel="stylesheet">

<link href="<%=cssUrl%>index.css" rel="stylesheet">

<link href="<%=cssUrl%>bootstrapValidator.min.css" rel="stylesheet" />

<script type="text/javascript" src="<%=jsUrl%>jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="<%=jsUrl%>bootstrap.min.js"></script>


<%@ include file="/commons/queryCondition.jsp" %>
</head>
<body>
<%@ include file="/commons/header.jsp"%>

<div class="container">
<br><br>

<br>

<div class="alert alert-info tip-success">

您一共买了 <b>${sessionScope.ShoppingCart.computerNumber } </b>件商品
应付: <b>¥ ${ sessionScope.ShoppingCart.totalMoney}</b>

</div>


<c:if test="${requestScope.errors != null }">
<div class="alert alert-danger text-center">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<b>${requestScope.errors }</b>
</div>

</c:if>


<div class="container" >
<form class="form-signin" action="computerServlet?method=cash" method="post" style="width:330px;margin:0 auto;">
<h2 class="form-signin-heading">请用信用卡完成支付!</h2>
<label for="inputEmail" class="sr-only">信用卡姓名</label>
<input type="text" name="username" class="form-control" style="margin-top:10px;margin-bottom: 20px;"placeholder="信用卡姓名" required="" autofocus="">
<label for="inputPassword" class="sr-only">信用卡账号</label>
<input type="text" id="inputPassword" name="accountId" class="form-control" placeholder="信用卡账号" required="">

<button class="btn btn-lg btn-primary btn-block" type="submit" style="margin-top:20px;">确认支付</button>
</form>
</div>

</div>



<%@ include file="/commons/footer.jsp"%>
</body>
</html>
文章作者: PanXiaoKang
文章链接: http://example.com/2020/04/16/%E7%99%BE%E8%84%91%E7%A7%91%E6%8A%80%E5%95%86%E5%9F%8E%E9%A1%B9%E7%9B%AE/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 向阳榆木
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论