目录
一、结合之前所学的相关技术,编写代码实现以下购物车功能
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@SetterInteger 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";@SneakyThrowsprotected 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: 86189Date: 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: 86189Date: 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: 86189Date: 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 {// 删除之前保存的CookieCookie[] 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: 86189Date: 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: 86189Date: 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>