ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

网上书店系统JSP+Servlet+MySQL源码:课程设计到答辩的完整方案

网上书店系统JSP+Servlet+MySQL源码:课程设计到答辩的完整方案 简介一份基于JSP技术的网上书店系统设计代码包面向计算机相关专业学生、JSP初学者以及需要完成毕业设计或课程项目的开发者。系统采用典型B/S架构覆盖图书查询、购买、订单处理、后台管理等常见业务可作为学习动态网页开发、数据库交互和MVC分层思想的实战范例。资源共六十个文件压缩包大小约二点一九兆字节包含二十个asp动态页面、图片与图标素材、数据库文件以及说明文档较为完整地呈现了站点前端页面、业务逻辑与数据存储等层级。目前已有五十四人学习下载适合需要快速参考完整实现流程的学习者。借助这份代码读者能梳理图书信息浏览、购物车、用户注册登录、订单提交与管理等模块的编码思路同时配合自带数据库和文档降低环境搭建与二次开发门槛。1. 网上书店系统设计代码一份能直接跑通的 JSP 项目学期末交课程设计最常见的翻车点不是需求文档而是代码。文档写得再漂亮Tomcat 一启动就 404答辩时手都在抖。这套网上书店系统设计代码定位就是解决这个问题——JSP Servlet MySQL 的完整可运行项目从数据库建表、后台图书管理到前台注册登录、购物车和订单一条链路全给齐。它不是零散片段而是导入 IDE、导 SQL、改连接、启动 Tomcat 就能演示的成套代码和课程设计常见的“基于 JSP 的系统设计与实现”选题完全对得上。适合两类人一类是 Java Web 课程设计或毕业设计选题为网上书店、在线书城的同学需要一份能看懂、能改、能讲清原理的参考实现另一类是刚学完 JSP 语法、想知道 Request、Response、Session 怎么在一个真实项目里串起来的初学者。代码不炫技走的是最经典的 JSP Servlet JavaBean 三层结构正好对应课程大纲里的考核点。2. 技术选型与工程结构为什么课程设计还在用 JSP2.1 课程大纲锁定的 JSP不是过时很多同学上来就问能不能换成 Spring Boot。能换但课程设计里JSP 是教学大纲明确要求的考核对象答辩老师会直接问“Servlet 生命周期是什么”“Session 怎么管理用户状态”。这套代码坚持 JSP Servlet JavaBean不是为了复古而是让每个页面请求都能被拆解成“页面 → Servlet → DAO → 数据库”的完整链路方便你在答辩时把 MVC 三个层次指给老师看。整套代码没有引入过多框架依赖连 JSTL 都是按需使用大部分页面逻辑用 JSP 内置对象就能完成。这样做的好处是你把代码部署到任何一台只装了 JDK 和 Tomcat 的机器上都能跑不会因为 Maven 仓库拉不下来依赖而卡住。课程设计的评分重点从来不是技术多新而是功能完整、结构清晰、能讲明白。2.2 工程目录先搞清楚每个文件在哪这套代码按标准的 Eclipse Dynamic Web Project 结构组织。拿到手先别急着跑把目录结构和每个包的作用过一遍后面改代码不会迷路。路径作用关键文件src/com/booksys/bean实体类对应数据库表User.java、Book.java、Order.java、Category.javasrc/com/booksys/dao数据访问层封装 JDBC 操作UserDao.java、BookDao.java、OrderDao.javasrc/com/booksys/servlet控制器层处理请求与跳转LoginServlet.java、BookServlet.java、CartServlet.java、OrderServlet.javasrc/com/booksys/util工具类数据库连接等DBUtil.java、PageBean.javaWebRoot/admin后台管理页面admin_login.jsp、book_list.jsp、book_add.jspWebRoot/index.jsp前台首页与图书列表index.jsp、register.jsp、login.jsp、cart.jspWebRoot/WEB-INF/web.xmlServlet 映射与欢迎页配置web.xmlsql/booksys.sql建库建表脚本直接导入 MySQL 即可我第一次拆这类项目的时候犯过一个错先翻代码翻到一半困在 Servlet 的跳转逻辑里。后来改成“先导数据库、再跑通一个完整流程比如用户注册→登录→下单”整个项目结构就自动在脑子里立起来了。这套代码也是这个顺序建议你按同样的路数来。2.3 运行环境版本配错直接启动失败这套代码对运行环境的要求非常具体版本不匹配是最容易踩的坑。组件推荐版本说明JDK1.8学校机房和多数实验室默认版本千万别装 JDK 17 跑老项目Tomcat8.5 或 9.0支持 Servlet 3.1/4.0与 JSP 2.3 兼容MySQL5.7驱动用mysql-connector-java-5.1.x.jarEclipse2020 之后即可自带 Tomcat 插件导入项目方便如果你本机只有 MySQL 8.0也能跑但要把驱动换成mysql-connector-java-8.0.x.jar同时连接 URL 里加时区参数。这个细节在第四章踩坑部分会详细说。先记住一个原则JDK 1.8 Tomcat 8.5 MySQL 5.7 是三件套在这套组合下跑通再谈升级。3. 数据库设计与核心模块实现从建表 SQL 到购物车闭环3.1 六张表的设计字段和约束一次说清这套代码的数据库设计是典型的小型电商结构共六张表管理员表、用户表、分类表、图书表、订单主表、订单明细表。购物车没有单独建表而是放在 Session 里这是课程设计最常见的做法理由是购物车是临时数据没必要落库答辩时可以解释为“减少无效 IO提升响应速度”。下面是核心建表脚本直接复制到 Navicat 或 MySQL 命令行执行CREATE DATABASE IF NOT EXISTS booksys DEFAULT CHARSET utf8mb4; USE booksys; CREATE TABLE admin ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20) NOT NULL UNIQUE, password VARCHAR(32) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20) NOT NULL UNIQUE, password VARCHAR(32) NOT NULL, realname VARCHAR(20), phone VARCHAR(11), address VARCHAR(100), reg_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(30) NOT NULL, description VARCHAR(200) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE book ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, author VARCHAR(50), price DECIMAL(10,2) NOT NULL, stock INT NOT NULL DEFAULT 0, category_id INT, publish_house VARCHAR(100), image VARCHAR(255), sales INT DEFAULT 0, FOREIGN KEY (category_id) REFERENCES category(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE orders ( id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL UNIQUE, user_id INT NOT NULL, total_price DECIMAL(10,2) NOT NULL, status INT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES user(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE order_item ( id INT PRIMARY KEY AUTO_INCREMENT, order_id INT NOT NULL, book_id INT NOT NULL, book_name VARCHAR(100), price DECIMAL(10,2), quantity INT, FOREIGN KEY (order_id) REFERENCES orders(id), FOREIGN KEY (book_id) REFERENCES book(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;表之间的关联关系用外键约束体现book表的category_id指向category表orders表的user_id指向user表order_item通过order_id挂到订单主表下。order_item里冗余了book_name和price两个字段这个设计是有意的——订单一旦生成图书价格和名称即使被修改历史订单里的快照依然不变。注意几个关键参数价格用DECIMAL(10,2)而不是FLOAT避免浮点运算精度问题密码字段用VARCHAR(32)配合 MD5 加密存储utf8mb4比utf8多支持 emoji虽然书店场景用不到但统一用更稳妥。库存stock和销量sales是后面下单减库存、按销量排序的基础。3.2 登录与会话Session 管理用户的完整写法登录是前后台都要用的核心功能。前台用户登录后用户信息存进 Session后台管理员登录后单独用admin字段标识。下面的UserDao登录方法演示了 JDBC 的标准写法public User login(String username, String password) { String sql SELECT * FROM user WHERE username? AND password?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, MD5Util.md5(password)); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { User user new User(); user.setId(rs.getInt(id)); user.setUsername(rs.getString(username)); user.setRealname(rs.getString(realname)); user.setPhone(rs.getString(phone)); user.setAddress(rs.getString(address)); return user; } } } catch (SQLException e) { e.printStackTrace(); } return null; }用PreparedStatement做参数化查询而不是字符串拼接 SQL是为了防 SQL 注入。密码在传入前先经过MD5Util.md5()加密库里存的不是明文。注意try-with-resources写法Connection、PreparedStatement、ResultSet 三个资源在语句块结束后自动关闭不用手动写一堆finally。登录成功后的 Servlet 会执行session.setAttribute(user, user)同时用session.setAttribute(admin, admin)区分角色。前端 JSP 里用c:if test${sessionScope.user ! null}控制“登录/注册”和“欢迎 xxx / 退出”两组按钮的切换这套代码里sessionScope的用法是现成的直接看header.jsp就能理解。3.3 图书分页与购物车两个必考功能分页查询是老师最爱考的知识点没有之一。这套代码的BookDao里封装了findByPage(pageNo, pageSize)方法public ListBook findByPage(int pageNo, int pageSize) { String sql SELECT b.*, c.name AS category_name FROM book b LEFT JOIN category c ON b.category_id c.id ORDER BY b.id DESC LIMIT ?, ?; ListBook list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (pageNo - 1) * pageSize); ps.setInt(2, pageSize); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Book book new Book(); book.setId(rs.getInt(id)); book.setName(rs.getString(name)); book.setPrice(rs.getBigDecimal(price)); book.setStock(rs.getInt(stock)); book.setCategoryName(rs.getString(category_name)); list.add(book); } } } catch (SQLException e) { e.printStackTrace(); } return list; }LIMIT两个参数的含义要能说出来第一个是偏移量等于(pageNo - 1) * pageSize即跳过前面多少条第二个是每页条数。首页pageNo1偏移 0第二页偏移 10假设每页 10 条。PageBean对象还会封装totalCount和totalPage总页数通过(totalCount pageSize - 1) / pageSize向上取整算出这个公式答辩时也常被问到。购物车是本项目另一个重点。下面是CartServlet里加入购物车的核心逻辑// 先取出 Session 中的购物车 Mapkey 是图书 idvalue 是购买数量 MapInteger, Integer cart (MapInteger, Integer) session.getAttribute(cart); if (cart null) { cart new HashMapInteger, Integer(); } int bookId Integer.parseInt(request.getParameter(bookId)); int quantity 1; if (cart.containsKey(bookId)) { quantity cart.get(bookId) 1; } cart.put(bookId, quantity); session.setAttribute(cart, cart);购物车用HashMapInteger, Integer存天然具备“同一本书重复加入只累加数量”的去重能力。cart.jsp里遍历这个 Map再从BookDao查出图书信息乘以数量算小计。这套设计代码量小、容易讲比用购物车表少一次数据库交互。3.4 下单减库存事务的两种打开方式下单是整个系统里唯一需要事务保护的环节扣库存、生成订单号、写订单明细三步要么全成功要么全失败。这套代码用的是最朴素的写法——关闭自动提交手动 commit/rollbackconn.setAutoCommit(false); try { // 1. 生成订单号并插入 orders 表 // 2. 遍历购物车逐条插入 order_item // 3. 更新 book 表 stock stock - quantity conn.commit(); } catch (SQLException e) { conn.rollback(); e.printStackTrace(); }setAutoCommit(false)是关键默认 JDBC 每条 SQL 自动提交下单必须关掉。中间任何一步抛异常rollback()会把已经执行的 SQL 全部撤销。你可以在第二步故意把库存改成负数验证效果这是答辩演示时的一个加分操作。4. 部署配置与避坑指南让项目在别人电脑上也能跑4.1 导入与启动Eclipse Tomcat 的标准路径拿到这套代码后不要直接双击文件。正确步骤是打开 EclipseFile → Import → Existing Projects into Workspace选择项目根目录导入后确认WebRoot被识别为 Web 根目录。然后在Servers视图新建一个 Tomcat 8.5 实例右键项目Add and Remove把项目部署进去启动 Tomcat浏览器访问http://localhost:8080/booksys/。如果项目名不是booksys注意web.xml里配置的欢迎页面和 Servlet 映射路径是跟着项目名走的改了项目名要同步检查访问 URL。代码里的数据库连接配置集中在DBUtil.java不是散落在每个 DAO 里改一处即可全局生效。4.2 MySQL 连接参数db.properties 里的每个值DBUtil.java会加载类路径下的db.properties内容大概长这样jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/booksys?useUnicodetruecharacterEncodingutf8useSSLfalse jdbc.usernameroot jdbc.password123456driver是 MySQL 5.7 的驱动类名换成 MySQL 8.0 要改成com.mysql.cj.jdbc.Driver。url里useUnicodetruecharacterEncodingutf8是中文不乱码的关键useSSLfalse是为了避免 MySQL 8.0 在连接时强制 SSL 校验导致警告如果是 MySQL 8.0还需要在 url 末尾加serverTimezoneAsia/Shanghai否则会报The server time zone value错误。username和password用自己的本地账号千万别不改就跑去连别人机器上的库。4.3 五个高频踩坑记录现象、原因、解决1. ClassNotFoundException: com.mysql.jdbc.Driver现象Tomcat 启动时控制台报找不到 JDBC 驱动类。 原因mysql-connector-java.jar没放进WebRoot/WEB-INF/lib目录或者放进去了没被部署。 解决把驱动 jar 包复制到WebRoot/WEB-INF/lib下右键项目 →Build Path → Configure Build Path → Add JARs再添加一次。两个地方要同步否则 Eclipse 编译时不报错Tomcat 运行时才崩。2. 页面全是问号中文乱码现象浏览器打开页面所有中文显示成???。 原因JSP 页面编码、数据库连接编码、数据库表编码三者不一致。 解决JSP 头部确认pageEncodingUTF-8db.properties的 url 里保留characterEncodingutf8book表字段已用utf8mb4。三个环节统一成 UTF-8乱码立刻消失。注意改完后重启 Tomcat别在浏览器里死命按 F5。3. Port 8080 was already in use现象Tomcat 启动立刻报端口占用Eclipse 控制台提示Port 8080 required by Tomcat 8.5 is already in use。 原因之前启动的 Tomcat 没关干净或者别的程序占了 8080。 解决Eclipse 里先看 Servers 视图是不是有运行中的实例先 Stop还不行就netstat -ano | findstr 8080查出 PID任务管理器里结束对应进程。血泪经验不要直接改 Tomcat 的端口为 8081改完所有访问路径都要跟着变答辩切换时容易慌。4. java.sql.SQLException: The server time zone value现象MySQL 8.0 环境下连接报时区错误。 原因MySQL 8.0 默认时区配置与 JDBC 驱动不兼容。 解决url 末尾加serverTimezoneAsia/Shanghai同时换com.mysql.cj.jdbc.Driver。记住一个组合MySQL 8.0 新驱动 serverTimezone三项缺一不可。5. 页面跳转后 Session 丢失永远提示未登录现象登录成功后跳到首页又变成未登录状态。 原因项目的 web.xml 里没有配置session-config的超时时间或者 Tomcat 的 context 配置有问题也可能是访问地址从http://localhost:8080/booksys换成了带 IP 的地址Session 不跨域名。 解决web.xml 里显式加session-configsession-timeout30/session-timeout/session-config浏览器访问地址统一用localhost不要混用127.0.0.1。5. 从能跑到能答辩验证清单与三个加分扩展5.1 功能验证清单答辩前逐项过一遍正式演示前按下面这张表把功能全点一遍。任何一个环节出问题先修好再进答辩教室。模块操作预期结果用户注册注册新账号提示成功数据库 user 表多一条记录用户登录错误密码登录页面提示密码错误不跳转图书分类首页点击分类只显示对应分类的图书分页点击下一页页码变化数据正确更新购物车同一本书加两次数量变为 2不是两行重复记录下单购物车结算库存减少订单表生成记录购物车清空后台登录admin 账号登录进入后台管理页后台添加图书填写表单提交前台首页立刻能看到新书5.2 低成本加分的三个扩展方向如果时间充裕优先做这三个扩展工作量小且在答辩时好讲。第一加一个关键字搜索框BookDao里多写一个findByName(String keyword)方法SQL 用WHERE name LIKE ?加%通配符首页表单提交到同一个 BookServlet。第二按销量排序book表已经有sales字段查图书时ORDER BY sales DESC一句话的事。第三给订单加一个“确认收货”状态流转orders表的status字段从 0 改到 1后台管理页就能展示“待发货 / 已发货”两种状态。5.3 答辩必问三题用这套代码的说话逻辑第一个问题MVC 在你的项目里怎么体现回答时直接把 Servlet、JSP、DAO 三层指给老师看——Model 是 Bean 和 DAOView 是 WebRoot 下的 JSPController 是 servlet 包里的类。第二个问题Session 和 Cookie 的区别结合登录功能说 Session 存用户信息在服务端Cookie 存 SessionID 在浏览器。第三个问题为什么购物车不建表答临时数据放 Session 减少数据库压力用户结算时才落库生成订单。这套代码我拆过不止一次每次给同学讲的时候都强调同一个习惯拿到任何网上书店或类似的 Java Web 项目第一件事不是编译运行而是先打开数据库脚本看表结构。从那以后我每次部署新项目都强制先过一遍建表 SQL再对页面、Servlet、DAO 的数据流。表结构立住了代码就跑不偏。希望帮到你。本文还有配套的精品资源点击获取
返回列表