目录
一、结合之前所学的相关技术,编写代码实现以下购物车功能
1. 我实现的功能运行截图如下
(1)商品列表页面home.jsp
(2)登录账号页面/未登录点击结账页面
(3)重新登录页面(记住上次登录的用户名和密码)
(4)点击任意商品加入购物车之后查看购物车
2. 数据库test存放的表格
(1)user表
(2)product表
3. 实体类
(1)User
(2)Product.java
4. CartController.java
5. JSP页面
(1)展现商品列表(home.jsp)
(2)登陆页面(login.jsp)
(3)登录后台处理页面(loginAction.jsp)
(4)结账页面(checkout.jsp)
(5)购物车页面(cart.jsp)
一、结合之前所学的相关技术,编写代码实现以下购物车功能
1. 编写一个页面,展现商品列表(静态页面),页面右上方有登陆、结账和查看购物车三个按钮,下方展示网站历史访问的人数
2. 用户点击商品后,可以将商品加入购物车
3. 用户点击登陆,跳转到登陆页面
4. 用户点击结账,若已登陆跳转至结账页面,否则跳转到登陆页面登陆后再跳转到结账页。
5. 用户点击查看购物车按钮,跳转至购物车页面,可查看购物车列表、增加商品数量或者删除商品
1. 我实现的功能运行截图如下
(1)商品列表页面home.jsp
(2)登录账号页面/未登录点击结账页面
(3)重新登录页面(记住上次登录的用户名和密码)
(4)点击任意商品加入购物车之后查看购物车
(5)增加或减少商品
(6)商品数量减为0时移除
(7)点击去结算,展示总金额
2. 数据库test存放的表格
(1)user表
(2)product表
导入jar包
3. 实体类
(1)User
package com.ryx.web.sy7;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
private String username;
private String password;
}
(2)Product.java
package com.ryx.web.sy7;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Product {
Integer id;
String name;
String imagePath;
BigDecimal price;
String description;
}
(3)ProductVo
package com.ryx.web.sy7;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
public class ProductVo extends Product {
@Getter
@Setter
Integer count; //统计数量
public ProductVo(Integer id, Integer count, String name, double price, String imagePath) {
super();
this.id = id;
this.count = count;
this.name = name;
this.price = BigDecimal.valueOf(price);
this.imagePath=imagePath;
}
}
4. CartController.java
package com.ryx.web.sy7;
import lombok.SneakyThrows;
import org.springframework.util.ObjectUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
@WebServlet(name = "shoppingCart", value = "/shoppingCart")
public class CartController extends HttpServlet {
// 连接数据库
private static final String DB_URL = "jdbc:mysql://localhost:3306/test";
private static final String DB_USERNAME = "root";
private static final String DB_PASSWORD = "abc1234";
@SneakyThrows
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.valueOf(request.getParameter("id"));
String op = request.getParameter("op");
String whereCome = request.getHeader("Referer");
String redirectPath = null;
// 如果在主页点击加入购物车超链接,不跳转
if (whereCome.equals("http://localhost:8080/sy7/home.jsp")) {
redirectPath = request.getContextPath() + "/sy7/home.jsp";
} else {
// 如果在购物车页面增加或删除商品也不跳转
redirectPath = request.getContextPath() + "/sy7/cart.jsp";
}
HttpSession session = request.getSession();
Map<Integer, ProductVo> cart = (Map<Integer, ProductVo>) session.getAttribute("cart");
if (ObjectUtils.isEmpty(cart)) {
cart = new HashMap();
}
switch (op) {
// 添加商品
case "add":
if (!ObjectUtils.isEmpty(cart.get(id))) {
ProductVo productVo = cart.get(id);
productVo.setCount(productVo.getCount() + 1);
cart.put(id, productVo);
} else {
Class.forName("com.mysql.jdbc.Driver");
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD)) {
String query = "SELECT * FROM product WHERE id = ?";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setInt(1, id);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
String name = rs.getString("name");
double price = rs.getDouble("price");
String imagePath = rs.getString("image_path");
Integer iid = rs.getInt("id");
ProductVo productVo = new ProductVo(iid, 1, name, price, imagePath);
cart.put(id, productVo);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
break;
// 减少商品
case "sub":
if (!ObjectUtils.isEmpty(cart.get(id))) {
ProductVo productVo = cart.get(id);
// 防止出现负数
if (productVo.getCount() > 1) {
productVo.setCount(productVo.getCount() - 1);
cart.put(id, productVo);
} else {
// 如果小于1则移除商品
cart.remove(id);
}
}
break;
}
session.setAttribute("cart", cart);
response.sendRedirect(redirectPath);
}
}
5. JSP页面
(1)展现商品列表(home.jsp)
CSS
table {
border-collapse: collapse;
width: 86%;
}
table, th, td {
border: 1px solid gainsboro;
}
td {
width: 200px;
}
.redText {
color: #FF0000;
}
.pinkTest {
color: lightpink;
}
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.DriverManager" %>
<%--
Created by IntelliJ IDEA.
User: 86189
Date: 2023/10/23
主页面展示商品
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>小煊的美妆铺</title>
</head>
<body>
<h1 align="center" class="pinkTest">欢迎来到小煊的美妆铺~</h1>
<div align="right" style="width: 90%"><a href="login.jsp">登录</a></div>
<div align="right" style="width: 90%"><a href="checkout.jsp">结算</a></div>
<div align="right" style="width: 90%"><a href="cart.jsp">查看购物车</a></div>
<br>
<table align="center">
<%---------------------- 获取商品数据 -----------------------------%>
<%
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//连接数据库
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "abc1234");
String query = "SELECT * FROM product";
stmt = conn.prepareStatement(query);
rs = stmt.executeQuery();
int count = 0;
while (rs.next()) {
int id = rs.getInt("id"); //商品编号
String name = rs.getString("name"); //商品名
double price = rs.getDouble("price"); //价格
String description = rs.getString("description"); //描述
String imagePath = rs.getString("image_path"); // 图片路径
//五个商品即换行
if (count % 5 == 0) {
out.println("<tr>");
}
%>
<td><br>
<%--------------------------图片-----------------------%>
<div align="center"><img src="<%=request.getContextPath()+imagePath%>" width="180px" height="240px"></div>
<%--------------------------商品描述-----------------------%>
<div> <%=name%><%=description%> </div>
<%--------------------------价格-----------------------%>
<div class="redText" align="left"> ¥:<%=price%> </div>
<%--------------------------加购-----------------------%>
<div align="right">
<form action="home.jsp" method="post">
<button onclick="void(0)"><a style="text-decoration: none"
href="<%=request.getContextPath()+"/shoppingCart?id="+id+"&op=add"%>"/>加入购物车
</button>
</form>
</div>
</td>
<%
//闭合标签
if (count % 5 == 4) {
out.println("</tr>");
}
count++;
}
//最后不足五个,自动闭合
if (count % 5 != 0) {
out.println("</tr>");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (Exception e) {
}
try {
stmt.close();
} catch (Exception e) {
}
try {
conn.close();
} catch (Exception e) {
}
}
%>
</table>
<br>
<%
// 初始化历史访问人数
Integer accessCount = (Integer) session.getAttribute("accessCount");
if (accessCount == null) {
accessCount = new Integer(0);
} else {
accessCount = new Integer(accessCount.intValue() + 1);
}
session.setAttribute("accessCount", accessCount);
%>
<div>历史访问人数:<%= accessCount %> </div>
</body>
</html>
(2)登陆页面(login.jsp)
JSP程序段+JS代码
<%-----------------------JSP程序段---------------------------%>
<%
request.setCharacterEncoding("UTF-8");
//一次性登录
String msg = request.getParameter("msg");
%>
<%
if (msg != null) {
String errorMessage = "账号或密码有误,请重新输入!";
%>
<script>
var error = '<%= errorMessage %>';
alert(error);
</script>
<%
}
%>
<%-- 读取Cookie --%>
<%
Cookie[] cookies = request.getCookies();
String savedUsername = null;
String savedPassword = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username")) {
savedUsername = cookie.getValue();
} else if (cookie.getName().equals("password")) {
savedPassword = cookie.getValue();
}
}
}
%>
HTML
<%--
Created by IntelliJ IDEA.
User: 86189
Date: 2023/10/13
登录页面
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<style>
body {
display: flex;
justify-content: center;
padding-top: 40px;
}
.titlecolor{
color: lightpink;
}
</style>
<title>登录页面</title>
</head>
<body>
<%-----------------------登录表单--------------------------%>
<form action="loginAction.jsp" method="post">
<h1 align="center" class="titlecolor">登录账号</h1>
<br>
<table width="300px">
<tr>
<td>
<laber for="username">用户名:</laber>
</td>
<td><input type="text" value="<%= savedUsername==null?"":savedUsername%>" id="username" name="username" required></td>
</tr>
<tr>
<td><label for="password">密码:</label></td>
<td><input type="password" value="<%= savedPassword==null?"":savedPassword%>" id="password" name="password" required></td>
<td align="right"><input type="submit" value="登录"></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name="remember" value="member">记住密码</td>
</tr>
</table>
</form>
</body>
</html>
(3)登录后台处理页面(loginAction.jsp)
<%@ page import="com.ryx.web.sy7.User" %>
<%@ page import="java.sql.*" %>
<%--
Created by IntelliJ IDEA.
User: 86189
Date: 2023/10/13
判断输入的用户信息是否存在数据库
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%!
public boolean validateUser(String username, String password) {
// 使用JDBC连接数据库
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/test"; //数据库
String user = "root"; //账户
String psword = "abc1234"; //密码
try {
try {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
// 获取数据库连接
connection = DriverManager.getConnection(url, user, psword);
} catch (SQLException e) {
e.printStackTrace();
}
try {
// 构造查询语句
String query = "SELECT * FROM test.user WHERE username = ? ";
// 创建PreparedStatement对象,并设置参数
statement = connection.prepareStatement(query);
statement.setString(1, username);
// 执行查询
resultSet = statement.executeQuery();
// 验证用户名和密码
if (resultSet.next()) {
String storedPassword = resultSet.getString("password");
if (storedPassword.equals(password)) {
return true;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
} finally {
// 关闭连接和释放资源
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
%>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
boolean isValidUser = validateUser(username, password);
//验证成功
if (isValidUser) {
// 创建形 Builder 构造者模式,链式编程
User user = User.builder()
.username(username)
.password(password)
.build();
String remember = request.getParameter("remember");
if (remember != null && remember.equals("member")) {
// 创建存储用户名和密码的Cookie对象
Cookie usernameCookie = new Cookie("username", username);
Cookie passwordCookie = new Cookie("password", password);
// 设置Cookie的有效期(设置为7天)
usernameCookie.setMaxAge(7 * 24 * 60 * 60); // 7天
passwordCookie.setMaxAge(7 * 24 * 60 * 60); // 7天
// 将Cookie添加到响应中
response.addCookie(usernameCookie);
response.addCookie(passwordCookie);
} else {
// 删除之前保存的Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username") || cookie.getName().equals("password")) {
cookie.setMaxAge(0); // 设置有效期为0,即立即删除
response.addCookie(cookie);
}
}
}
}
session.setAttribute("user", user);
//跳转到其他页面
response.sendRedirect("home.jsp");
} else {
//验证失败,提示出错
response.sendRedirect("login.jsp?msg=failed");
}
%>
(4)结账页面(checkout.jsp)
HTML+JSP+JSTL
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="com.ryx.web.sy7.User" %>
<%@ page import="java.util.Map" %>
<%--
Created by IntelliJ IDEA.
User: 86189
Date: 2023/10/21
结算页面
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<%--------------------判断用户是否登录-----------------------%>
<%
//存储变量
User user = (User) session.getAttribute("user");
// 未登录用户跳转到登录页面
if (user == null) {
response.sendRedirect("login.jsp");
}
%>
<head>
<meta charset="UTF-8">
<title>结算</title>
</head>
<body>
<%----------------- 获取购物车中的商品 ------------------------%>
<h1 align="center" style="color: lightpink">订单信息</h1>
<%
session = request.getSession();
Map<Integer, Integer> cart = (Map<Integer, Integer>) session.getAttribute("cart");
if (cart == null) {
out.println("购物车为空");
return;
}
%>
<%--计算总价钱--%>
<c:set var="totalAmount" value="0"/>
<c:forEach var="entry" items="${cart.entrySet()}">
<c:set var="product" value="${entry.value}"/>
<%--单个商品的总额--%>
<c:set var="amount" value="${product.price * product.count}"/>
<%--所有商品的总额--%>
<c:set var="totalAmount" value="${totalAmount + amount}"/>
</c:forEach>
<div align="center">
<h2>您应支付:¥${totalAmount}</h2>
<form action="checkout.jsp" method="POST">
<input type="submit" value="确认订单">
</form>
</div>
</body>
</html>
(5)购物车页面(cart.jsp)
CSS
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid gainsboro;
}
.titleTest {
color: lightpink;
}
td {
width: 20%;
}
a {
text-decoration: none;
}
HTML
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%--
Created by IntelliJ IDEA.
User: 86189
Date: 2023/10/21
购物车页面
--%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>购物车</title>
</head>
<body>
<h1 align="center" class="titleTest">我的购物车</h1>
<c:if test="${cart!=null && cart.size()>0}">
<table style="width: 1000px" align="center">
<tr>
<th>商品信息</th>
<th>单价</th>
<th>数量</th>
<th>金额</th>
</tr>
<c:forEach var="entry" items="${cart.entrySet()}">
<tr>
<c:set var="product" value="${entry.value}"/>
<%----------------------商品信息--------------------%>
<td><img src="${request.contextPath}${product.imagePath}" width="60px" height="80px">${product.name}</td>
<%----------------------单价--------------------%>
<td align="center">¥:${product.price}</td>
<%----------------------数量-/+--------------------%>
<td align="center">
<button onclick="void(0)"><a href="
<%=request.getContextPath()+"/shoppingCart?op=sub&id="%>${product.id}
"/>-
</button>
${product.count}
<button onclick="void(0)"><a href="
<%=request.getContextPath()+"/shoppingCart?op=add&id="%>${product.id}
"/>+
</button>
</td>
<%----------------------金额--------------------%>
<td align="center">¥:${product.count*product.price}</td>
</tr>
</c:forEach>
</table>
</c:if>
<br><br>
<div style="width: 90%" align="right">
<a href="home.jsp">继续购物</a>
<a href="checkout.jsp">去结算</a>
</div>
</body>
</html>