引言:
Web应用开发是一个多方面的过程,涉及多种技术和步骤。在本篇博客中,我们将讨论开发一个基本的电子商务网站,从登录到购物车结账的关键步骤。我们将介绍如何处理用户登录、管理购物车、生成订单以及其他与电子商务网站相关的关键概念和技术。
第一部分: 用户登录
在任何电子商务网站中,用户登录是一个关键步骤。在我们的示例中,我们使用了Java Servlet来处理用户登录。以下是一些关键步骤:
-
创建登录表单和Servlet:我们设计了一个简单的登录表单,用户需要输入用户名和密码。用户提交表单后,请求将被发送到一个Servlet来验证用户身份。——LoginServlet和login.jsp
-
验证用户信息:在Servlet中,我们检查用户提供的用户名和密码是否与存储在数据库中的信息匹配。如果匹配成功,用户被认证。
-
会话管理:一旦用户登录,我们使用会话(Session)来跟踪用户的状态。如果用户成功登录,我们将用户名存储在会话中,以便在购物车和结账过程中识别用户。
-
记录历史访问人数:作为一个额外的功能,我们还记录了历史访问人数。我们使用ServletContext来存储和更新历史访问人数,这有助于了解网站的受欢迎程度。——SiteVisitorCounterListener
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
//@WebServlet("/LoginServlet")
@WebServlet(name = "LoginServlet", value = "/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理登录逻辑
// 如果登录成功,设置session中的用户信息
// 如果登录失败,显示错误消息
// 跳转至结账或返回商品列表页面
String username = request.getParameter("username");
String password = request.getParameter("password");
boolean rememberMe = "true".equals(request.getParameter("rememberMe"));
// 进行用户身份验证逻辑,这里使用简单的示例
if ("user123".equals(username) && "password123".equals(password)) {
// 登录成功,设置用户信息到Session
HttpSession session = request.getSession();
session.setAttribute("username", username);
session.setAttribute("password",password);
// 如果用户选择“记住我”,设置一个持久性Cookie
if (rememberMe) {
Cookie usernameCookie = new Cookie("rememberedUsername", username);
Cookie passwordCookie = new Cookie("rememberedPassword", password);
usernameCookie.setMaxAge(86400); // 1天
passwordCookie.setMaxAge(86400); // 1天
response.addCookie(usernameCookie);
response.addCookie(passwordCookie);
}
response.sendRedirect("CheckoutServlet");
} else {
// 登录失败,显示错误消息
request.setAttribute("error", "用户名或密码错误");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.Map" %>
<html>
<head>
<title>登录</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
}
h1 {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
}
form {
background-color: #fff;
width: 300px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
label[for="rememberMe"] {
display: inline;
margin-right: 10px;
}
input[type="checkbox"] {
display: inline;
margin-right: 5px;
}
input[type="submit"] {
background-color: #0077cc;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 3px;
cursor: pointer;
}
.error {
color: red;
margin-top: 10px;
}
</style>
</head>
<body>
<h1>用户登录</h1>
<form action="LoginServlet" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required><br><br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required><br><br>
<%
String error = (String) request.getAttribute("error");
if (error != null && !error.isEmpty()) {
%>
<p class="error"><%= error %></p>
<%
}
%>
<label for="rememberMe">记住我:</label>
<input type="checkbox" id="rememberMe" name="rememberMe" value="true"><br><br>
<input type="submit" value="登录">
</form>
</body>
<script>
// 检查是否存在Cookie并提取用户名和密码
function getCookieValue(cookieName) {
const name = cookieName + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const cookieArray = decodedCookie.split(';');
for (let i = 0; i < cookieArray.length; i++) {
let cookie = cookieArray[i];
while (cookie.charAt(0) === ' ') {
cookie = cookie.substring(1);
}
if (cookie.indexOf(name) === 0) {
return cookie.substring(name.length, cookie.length);
}
}
return "";
}
// 获取用户名和密码
const rememberedUsername = getCookieValue("rememberedUsername");
const rememberedPassword = getCookieValue("rememberedPassword");
// 填充用户名和密码到表单字段
document.getElementById("username").value = rememberedUsername;
document.getElementById("password").value = rememberedPassword;
</script>
</html>
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
@WebListener
public class SiteVisitorCounterListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// 初始化网站历史访问人数计数
sce.getServletContext().setAttribute("visitors", 0);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 在应用关闭时执行清理操作
}
}
第二部分: 购物车管理
电子商务网站通常提供一个购物车,用户可以将所选商品添加到其中。在我们的示例中,购物车的管理是一个重要环节:
-
添加商品到购物车:我们展示了如何在网页上显示商品,并提供"加入购物车"按钮。当用户点击该按钮时,请求将发送到一个Servlet以更新购物车。——AddToCartServlet
-
购物车数据结构:我们使用了一个
Map
来表示购物车,其中商品名称是键,数量是值。购物车数据存储在用户的会话中,以便跟踪用户的购买。——ViewCartServlet -
从购物车中删除商品:我们展示了如何创建"删除"按钮,以便用户可以删除购物车中的商品。这会触发Servlet来更新购物车。——RemoveFromCartServlet
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
//@WebServlet("/AddToCartServlet")
@WebServlet(name = "AddToCartServlet", value = "/AddToCartServlet")
public class AddToCartServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String product = request.getParameter("product");
HttpSession session = request.getSession();
Map<String, Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
if (cart == null) {
cart = new HashMap<>();
}
cart.put(product, cart.getOrDefault(product, 0) + 1);
session.setAttribute("cart", cart);
response.sendRedirect("product_list.jsp");
}
}
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.util.Map;
@WebServlet(name = "RemoveFromCartServlet", value = "/RemoveFromCartServlet")
public class RemoveFromCartServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取要删除的商品名称
String productToRemove = request.getParameter("product");
// 从购物车中移除商品
Map<String, Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");
if (cart != null) {
cart.remove(productToRemove);
}
// 重定向到购物车页面
response.sendRedirect("cart.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理POST请求,如果需要的话
}
}
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;
//@WebServlet("/ViewCartServlet")
@WebServlet(name = "ViewCartServlet", value = "/ViewCartServlet")
public class ViewCartServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Map<String, Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
request.setAttribute("cart", cart);
request.getRequestDispatcher("cart.jsp").forward(request, response);
}
}
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>购物车</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
}
h1 {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
}
ul {
list-style: none;
padding: 0;
}
li {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: 10px;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
a {
text-decoration: none;
color: #0077cc;
}
a:hover {
text-decoration: underline;
}
.empty-cart {
text-align: center;
}</style>
</head>
<body>
<h1>购物车</h1>
<ul>
<%
Map<String, Integer> cart = (Map<String, Integer>) request.getAttribute("cart");
if (cart != null) {
for (Map.Entry<String, Integer> entry : cart.entrySet()) {
%>
<li><%= entry.getKey() %> - 数量: <%= entry.getValue() %> <a href="RemoveFromCartServlet?product=<%= entry.getKey() %>">删除</a></li>
<%
}
} else {
%>
<p>购物车为空</p>
<%
}
%>
</ul><br><br>
<a href="product_list.jsp">返回商品列表</a>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>商品列表</title>
<%
// 获取ServletContext
ServletContext servletContext = request.getServletContext();
// 获取当前访问人数
Integer visitors = (Integer) servletContext.getAttribute("visitors");
// 增加访问人数
visitors = (visitors != null) ? visitors + 1 : 1;
// 更新ServletContext中的访问人数
servletContext.setAttribute("visitors", visitors);
// 检查用户是否已登录
String username = (String) session.getAttribute("username");
%>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
}
h1 {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
}
ul {
list-style: none;
padding: 0;
}
li {
background-color: #fff;
margin: 10px;
padding: 10px;
border: 1px solid #ddd;
}
a {
text-decoration: none;
color: #0077cc;
}
div.header {
background-color: #333;
color: #fff;
text-align: right;
padding: 10px;
}
div.buttons {
float: right;
margin-top: 20px; /* 调整这里的值以控制上移的幅度 */
}
</style>
</head>
<body>
<h1>商品列表</h1>
<div class="header">
<div class="buttons">
<% if (username != null) { %>
<!-- 用户已登录,不显示登录链接 -->
<a href="CheckoutServlet">结账</a> |
<% } else { %>
<!-- 用户未登录,显示登录链接 -->
<a href="LoginServlet">登录</a> |
<% } %>
<a href="ViewCartServlet">查看购物车</a>
</div>
</div>
<ul>
<li>商品1 - 100元 <a href="AddToCartServlet?product=product1">加入购物车</a></li>
<li>商品2 - 200元 <a href="AddToCartServlet?product=product2">加入购物车</a></li>
<!-- 添加更多商品 -->
</ul>
<p>网站历史访问人数: <%= application.getAttribute("visitors") %></p>
</body>
</html>
第三部分: 结账流程
结账是电子商务网站的关键功能之一。在我们的示例中,结账包括以下步骤:
-
结账按钮:用户登录后,可以单击"结账"按钮,进入结账流程。——checkout.jsp
-
生成订单:我们创建了一个订单对象,包括订单号、用户名、商品列表和订单总额。订单数据通常存储在数据库中,但在本示例中,我们存储在会话中。——Order类
-
清空购物车:一旦订单生成,购物车应该被清空。购物车是一个临时的存储区,用户每次下单后都会清空购物车。——CheckoutServlet
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;
@WebServlet(name = "CheckoutServlet", value = "/CheckoutServlet")
public class CheckoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
if (username != null) {
Map<String, Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
if(cart!=null){Order order = generateOrder(username, cart);
order.storeInSession(session); // 存储订单信息到 HttpSession
// 清空购物车
cart.clear();
response.sendRedirect("checkout.jsp");}
else{
response.sendRedirect("cart.jsp");
}
} else {
response.sendRedirect("login.jsp");
}
}
private Order generateOrder(String username, Map<String, Integer> cart) {
Order order = new Order();
order.setOrderNumber(generateOrderNumber());
order.setUsername(username);
// 添加购物车中的商品到订单
for (Map.Entry<String, Integer> entry : cart.entrySet()) {
String productName = entry.getKey();
int quantity = entry.getValue();
order.addOrderItem(productName, quantity);
}
return order;
}
private String generateOrderNumber() {
// 生成唯一的订单号的逻辑
return "ORD" + System.currentTimeMillis();
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.example.shoppingcart.Order" %>
<%@ page import="java.util.Map" %>
<html>
<head>
<title>结账</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
}
h1 {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
}
.order-container {
background-color: #fff;
width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
ul {
list-style: none;
padding: 0;
}
li {
margin-bottom: 10px;
}
a {
display: inline-block;
background-color: #0077cc;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 3px;
text-decoration: none;
margin-top: 10px;
}
</style>
</head>
<body>
<h1>结账页面</h1>
<!-- 显示订单信息 -->
<%
Order order = Order.retrieveFromSession(request.getSession());
if (order != null) {
%>
<p>订单号: <%= order.getOrderNumber() %></p>
<p>用户名: <%= order.getUsername() %></p>
<p>订单详情:</p>
<ul>
<%
Map<String, Integer> orderItems = order.getOrderItems();
for (Map.Entry<String, Integer> entry : orderItems.entrySet()) {
String productName = entry.getKey();
int quantity = entry.getValue();
%>
<li><%= productName %> - 数量: <%= quantity %></li>
<%
}
%>
</ul>
<p>订单总额: <%= order.getTotalAmount() %> 元</p>
<%
} else {
%>
<p>没有找到订单信息。</p>
<%
}
%>
<!-- 添加结账按钮等其他操作 -->
<a href="product_list.jsp">返回首页</a>
</body>
</html>
第四部分: 页面美化
最后,我们展示了如何美化Web页面,以提供更好的用户体验。这包括添加样式、布局和改进页面的外观。——各个JSP文件中的style标签
<style><!--product_list.jsp-->
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
}
h1 {
background-color: #333;
color: #fff;
padding: 20px;
text-align: center;
}
ul {
list-style: none;
padding: 0;
}
li {
background-color: #fff;
margin: 10px;
padding: 10px;
border: 1px solid #ddd;
}
a {
text-decoration: none;
color: #0077cc;
}
div.header {
background-color: #333;
color: #fff;
text-align: right;
padding: 10px;
}
div.buttons {
float: right;
margin-top: 20px; /* 调整这里的值以控制上移的幅度 */
}
</style>
结论:
电子商务网站开发涉及多个关键步骤,包括用户登录、购物车管理和结账流程。通过使用Java Servlet和Session管理,我们演示了如何处理这些功能。通过改进页面的外观,可以提高用户体验。本文仅是一个入门示例,真正的电子商务网站可能需要更多功能和安全性。
希望这篇博客有助于理解Web应用开发中的关键步骤,并为开发电子商务网站提供指导。
注:在博客中添加Servlet和Listener的配置说明,通常可以包含在Web应用的web.xml
文件中。