目錄
一、結合之前所學的相關技術,編寫代碼實現以下購物車功能
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>