1. 项目概述
这个JavaWeb实训项目是一个典型的图书管理系统,采用Servlet作为核心控制层技术实现。作为计算机专业学生常见的课程设计选题,它涵盖了Web开发中最基础的MVC模式实践。我在指导学生的过程中发现,很多人在第三天实训时容易卡在Servlet与数据库交互这个关键环节。
图书管理系统看似简单,但完整实现需要处理用户认证、图书CRUD、借阅归还等核心业务逻辑。通过这个项目,学生能够掌握Servlet生命周期、请求分发、会话管理等核心概念,同时理解Web应用与数据库的交互模式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 核心组件选型
采用经典的JavaWeb技术栈:
- 前端:JSP+JSTL+EL表达式
- 控制层:Servlet(继承HttpServlet)
- 数据访问:JDBC直连
- 数据库:MySQL 5.7+
注意:虽然现在流行Spring框架,但教学场景下直接使用Servlet更能让学生理解Web底层原理。实际企业开发中建议使用Spring MVC。
2.2 项目目录结构规范
标准Maven项目结构:
code复制src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── library/
│ │ ├── controller/ # Servlet类
│ │ ├── dao/ # 数据访问层
│ │ ├── model/ # 实体类
│ │ └── util/ # 工具类
│ ├── resources/ # 配置文件
│ └── webapp/
│ ├── WEB-INF/
│ │ └── lib/ # 依赖jar包
│ ├── css/
│ ├── js/
│ └── jsp/ # 视图文件
└── test/ # 测试代码
3. 核心功能实现
3.1 Servlet配置与映射
在web.xml中配置Servlet的经典方式:
xml复制<servlet>
<servlet-name>BookServlet</servlet-name>
<servlet-class>com.library.controller.BookServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BookServlet</servlet-name>
<url-pattern>/book</url-pattern>
</servlet-mapping>
3.2 数据库连接管理
推荐使用DBCP连接池配置:
java复制public class DBUtil {
private static DataSource dataSource;
static {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/library?useSSL=false");
ds.setUsername("root");
ds.setPassword("123456");
ds.setInitialSize(5);
ds.setMaxTotal(10);
dataSource = ds;
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
3.3 典型CRUD实现示例
图书新增的Servlet处理:
java复制protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String isbn = request.getParameter("isbn");
String title = request.getParameter("title");
String author = request.getParameter("author");
try (Connection conn = DBUtil.getConnection()) {
String sql = "INSERT INTO books(isbn, title, author) VALUES(?,?,?)";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, isbn);
stmt.setString(2, title);
stmt.setString(3, author);
int rows = stmt.executeUpdate();
if(rows > 0) {
request.setAttribute("message", "添加成功");
} else {
request.setAttribute("error", "添加失败");
}
} catch(SQLException e) {
e.printStackTrace();
request.setAttribute("error", "数据库异常:" + e.getMessage());
}
request.getRequestDispatcher("/book/add_result.jsp").forward(request, response);
}
4. 关键问题解决方案
4.1 中文乱码处理
必须统一编码处理:
java复制// 在Servlet的init()方法中设置
public void init() throws ServletException {
super.init();
// 设置请求编码
setInitParameter("encoding", "UTF-8");
}
// 在每个doPost方法开始处
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
4.2 分页查询实现
使用MySQL的LIMIT分页:
java复制public List<Book> getBooksByPage(int pageNo, int pageSize) {
List<Book> books = new ArrayList<>();
String sql = "SELECT * FROM books LIMIT ?,?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, (pageNo-1)*pageSize);
stmt.setInt(2, pageSize);
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
Book book = new Book();
book.setId(rs.getInt("id"));
book.setIsbn(rs.getString("isbn"));
book.setTitle(rs.getString("title"));
books.add(book);
}
} catch(SQLException e) {
e.printStackTrace();
}
return books;
}
5. 项目优化建议
5.1 使用过滤器统一处理
创建EncodingFilter解决编码问题:
java复制@WebFilter("/*")
public class EncodingFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
}
5.2 采用DAO模式重构
定义BookDAO接口:
java复制public interface BookDAO {
boolean addBook(Book book);
boolean deleteBook(int id);
boolean updateBook(Book book);
Book getBookById(int id);
List<Book> getAllBooks();
List<Book> getBooksByPage(int pageNo, int pageSize);
}
6. 常见错误排查
6.1 404错误常见原因
-
URL映射错误
- 检查web.xml配置或@WebServlet注解
- 确认上下文路径是否正确
-
文件位置错误
- JSP文件必须放在webapp目录下
- 静态资源路径要正确
6.2 数据库连接问题
典型错误现象:
code复制java.sql.SQLException: No suitable driver found for jdbc:mysql://...
解决方案:
- 确认mysql-connector-java.jar已放入WEB-INF/lib
- 检查JDBC URL格式是否正确
- 数据库服务是否启动
7. 项目部署要点
7.1 Tomcat配置建议
在conf/server.xml中添加:
xml复制<Context docBase="library" path="/library" reloadable="true">
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
7.2 数据库初始化脚本
建议提供SQL建表脚本:
sql复制CREATE DATABASE IF NOT EXISTS library DEFAULT CHARSET utf8;
USE library;
CREATE TABLE books (
id INT PRIMARY KEY AUTO_INCREMENT,
isbn VARCHAR(20) NOT NULL UNIQUE,
title VARCHAR(100) NOT NULL,
author VARCHAR(50),
publish_date DATE,
price DECIMAL(10,2),
status TINYINT DEFAULT 1
);
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(30) NOT NULL UNIQUE,
password VARCHAR(32) NOT NULL,
real_name VARCHAR(20),
role TINYINT DEFAULT 0
);
8. 评分要点解析
根据多年指导经验,高分作业需要:
-
功能完整度(占40%)
- 基础CRUD功能
- 用户权限控制
- 借阅归还业务
-
代码质量(占30%)
- 合理的分层架构
- 规范的命名
- 适当的注释
-
界面友好度(占20%)
- 基本的CSS样式
- 表单验证
- 操作反馈
-
报告完整性(占10%)
- 设计文档
- 使用说明
- 遇到的问题及解决方案
9. 扩展学习建议
完成基础功能后,可以尝试:
- 增加Redis缓存热门图书
- 使用AJAX实现无刷新操作
- 添加图书封面图片上传功能
- 实现Excel导入导出
- 集成简单的统计分析图表
我在实际项目指导中发现,很多学生会在第三天遇到Servlet与JSP数据传递的问题。一个实用的技巧是:在Servlet中处理好业务逻辑后,将结果数据存入request作用域,再通过RequestDispatcher转发到JSP页面,这样既能保持数据又能维持一次请求。
