目录
一、结合之前所学的相关技术,编写代码实现以下购物车功能
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@Builderpublic 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@AllArgsConstructorpublic 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>