前言
在当今数字化时代,电商平台已成为商业活动的重要组成部分。作为一名Java开发者,掌握电商后台管理系统的开发技能至关重要。本文将带你从零开始,使用经典的Servlet+JSP技术栈构建一个功能完整的电商后台管理系统。这个项目不仅适合初学者学习Java Web开发,也能帮助有经验的开发者巩固基础知识。
一、项目概述
1.1 系统功能模块
我们的电商后台管理系统主要包含以下核心模块:
-
用户管理:管理员账号的CRUD操作、权限分配
-
商品管理:商品分类、商品信息的增删改查
-
订单管理:订单查询、状态修改、发货处理
-
数据统计:销售数据可视化展示
-
系统设置:基础参数配置、日志管理
1.2 技术选型
技术栈 | 说明 |
---|---|
前端 | JSP + Bootstrap + jQuery |
后端 | Servlet + JavaBean |
数据库 | MySQL |
服务器 | Tomcat 9.x |
开发工具 | Eclipse/IntelliJ IDEA |
项目管理 | Maven |
二、环境搭建
2.1 开发环境准备
JDK安装:推荐JDK 1.8及以上版本
java -version
Tomcat配置:下载Tomcat 9.x并配置到开发环境
<!-- Maven依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
数据库设计:创建电商系统基础表结构
CREATE TABLE `admin_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`real_name` varchar(50) DEFAULT NULL,
`status` tinyint(4) DEFAULT '1',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
三、核心功能实现
3.1 用户登录模块
LoginServlet.java
@WebServlet("/admin/login")
public class LoginServlet extends HttpServlet {
private AdminUserService adminUserService = new AdminUserServiceImpl();
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
AdminUser adminUser = adminUserService.login(username, password);
if(adminUser != null) {
// 登录成功,将用户信息存入session
request.getSession().setAttribute("loginUser", adminUser);
response.sendRedirect("index.jsp");
} else {
request.setAttribute("msg", "用户名或密码错误");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}
登录页面login.jsp关键代码
<div class="container">
<form action="${pageContext.request.contextPath}/admin/login" method="post">
<h2 class="form-signin-heading">电商后台管理系统</h2>
<c:if test="${not empty msg}">
<div class="alert alert-danger">${msg}</div>
</c:if>
<input type="text" name="username" class="form-control" placeholder="用户名" required autofocus>
<input type="password" name="password" class="form-control" placeholder="密码" required>
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
</form>
</div>
3.2 商品管理模块
商品分页查询实现
@WebServlet("/admin/product/list")
public class ProductListServlet extends HttpServlet {
private ProductService productService = new ProductServiceImpl();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int page = 1;
int size = 10;
try {
page = Integer.parseInt(request.getParameter("page"));
} catch (NumberFormatException e) {}
try {
size = Integer.parseInt(request.getParameter("size"));
} catch (NumberFormatException e) {}
PageInfo<Product> pageInfo = productService.findByPage(page, size);
request.setAttribute("pageInfo", pageInfo);
request.getRequestDispatcher("/admin/product_list.jsp").forward(request, response);
}
}
商品列表JSP页面片段
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>ID</th>
<th>商品名称</th>
<th>价格</th>
<th>库存</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${pageInfo.list}" var="product">
<tr>
<td>${product.id}</td>
<td>${product.name}</td>
<td>${product.price}</td>
<td>${product.stock}</td>
<td>
<c:if test="${product.status == 1}">上架</c:if>
<c:if test="${product.status == 0}">下架</c:if>
</td>
<td>
<a href="edit?id=${product.id}" class="btn btn-sm btn-primary">编辑</a>
<a href="javascript:deleteProduct(${product.id})" class="btn btn-sm btn-danger">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<!-- 分页导航 -->
<ul class="pagination">
<c:if test="${pageInfo.hasPreviousPage}">
<li><a href="list?page=${pageInfo.prePage}&size=${pageInfo.pageSize}">«</a></li>
</c:if>
<c:forEach items="${pageInfo.navigatepageNums}" var="nav">
<li <c:if test="${nav == pageInfo.pageNum}">class="active"</c:if>>
<a href="list?page=${nav}&size=${pageInfo.pageSize}">${nav}</a>
</li>
</c:forEach>
<c:if test="${pageInfo.hasNextPage}">
<li><a href="list?page=${pageInfo.nextPage}&size=${pageInfo.pageSize}">»</a></li>
</c:if>
</ul>
四、项目优化与技巧
4.1 使用过滤器实现权限控制
@WebFilter("/admin/*")
public class AdminFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession session = httpRequest.getSession();
AdminUser loginUser = (AdminUser) session.getAttribute("loginUser");
// 排除登录页面和登录请求
String uri = httpRequest.getRequestURI();
if(uri.endsWith("login.jsp") || uri.endsWith("login")) {
chain.doFilter(request, response);
return;
}
if(loginUser == null) {
httpResponse.sendRedirect(httpRequest.getContextPath() + "/admin/login.jsp");
return;
}
chain.doFilter(request, response);
}
}
4.2 数据库连接池配置
使用Apache Commons DBCP2实现连接池:
<!-- pom.xml添加依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.8.0</version>
</dependency>
DBUtil.java
public class DBUtil {
private static BasicDataSource dataSource;
static {
dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/ecommerce?useSSL=false&serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("password");
dataSource.setInitialSize(5);
dataSource.setMaxTotal(20);
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
五、项目部署与测试
5.1 部署到Tomcat服务器
将项目打包为WAR文件
mvn clean package
将生成的WAR文件复制到Tomcat的webapps目录下
启动Tomcat服务器
catalina.sh run
5.2 系统测试要点
-
功能测试:
-
用户登录/登出功能
-
商品CRUD操作
-
订单状态流转
-
-
性能测试:
-
使用JMeter模拟多用户并发操作
-
数据库查询性能优化
-
-
安全测试:
-
SQL注入测试
-
XSS攻击防护
-
CSRF防护
-
六、项目总结与扩展
通过这个电商后台管理系统的开发,我们掌握了以下核心技术:
-
Servlet的生命周期和工作原理
-
JSP与EL表达式的使用
-
MVC设计模式的实践
-
数据库连接池的配置与使用
-
基本的Web安全防护措施
项目扩展方向:
-
引入Redis缓存热门商品数据
-
使用POI实现数据导出Excel功能
-
集成第三方支付接口
-
开发RESTful API供移动端调用
-
使用WebSocket实现实时订单通知
结语
Servlet+JSP作为Java Web开发的经典技术组合,虽然现在有更多现代化的框架可供选择,但理解这些基础技术的工作原理对于成为一名优秀的Java开发者至关重要。希望这个电商后台管理系统的实践项目能帮助你夯实基础,为学习更高级的框架打下坚实基础。
如果你在实现过程中遇到任何问题,欢迎在评论区留言讨论。也欢迎关注我的CSDN账号,获取更多Java开发实战教程!