ARTICLE DETAIL

资讯详情

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

JSP商品评价系统部署实战:从class文件到Tomcat运行的全流程解析

JSP商品评价系统部署实战:从class文件到Tomcat运行的全流程解析 简介一份基于JSP实现的商品管理与评价系统完整源码包面向Java Web学习者与电商系统开发者。压缩包内含275个文件约1.39MB涵盖38个JSP页面、58个Java类与58个class文件、2个jar包及大量gif/jpg图片素材其中JSP负责前端交互与页面展示Java类封装数据处理与业务逻辑图片资源用于商品图示与界面美化结构清晰便于直接部署学习。系统实现了管理员对商品信息的增删改查以及浏览者对商品评分评论功能并涉及用户登录验证、权限控制等辅助模块是理解JSP、Servlet、JavaBeans与数据库交互的典型案例。配合描述中提到的MVC设计思路开发者可借此掌握动态网页开发中前后端协作的完整流程。目前已有131人学习下载适合课程设计、毕业设计或入门级电商项目参考。这份资源的价值在于完整可运行的代码与清晰的模块划分能帮助读者快速上手JSP项目开发。1. 一份只有 class 和图片的 JSP 资源star.zip 到底能干什么接手一个名叫 star.zip 的课程设计压缩包时第一眼很容易劝退里面没有常见的 .jsp 文件只有 jiangwei.bmp、daqiao.bmp 这类商品图片以及 SmartUpload.class、ComDAO.class、crDAO.class 几个编译后的 class 文件。别急着删这其实是很多早期 JSP 教学项目典型的打包方式——页面文件、配置文件和编译产物被放到同一个 web 目录里压缩时目录层级没展开所以你只看到了一部分。这个商品管理与评价系统核心就是管理员维护商品信息浏览者登录后给商品评分用 JSP Servlet DAO 把一条增删改查和评价计算链路完整跑通。它适合两类人一类是正在做 Java Web 课程设计、需要一套能复现的现场项目的人另一类是想拆着学 DAO、SmartUpload、MVC 如何在小项目里落地的初学者。把环境配好后它确实能跑起来下面就是我从解压到改造的完整实操记录。2. JSP 商品评价系统的运行骨架从文件清单推导 MVC 与数据表2.1 先认手里的文件class 与 bmp 各是什么角色下载资源里的文件看似零散其实每类文件对应一个明确的职责。先看 bmp 文件jiangwei.bmp、daqiao.bmp、Stranger.bmp、zhangliao.bmp、smyi.bmp、guanyu.bmp这些明显是商品展示图。选用 bmp 格式说明项目写得很早后来验证时浏览器大概率打不开这种老格式这是后话我在避坑章节会专门讲。再看 class 文件。SmartUpload.class 是 JSP 时代非常常用的文件上传组件商品图片上传就靠它。ComDAO.class 里的 Com 我推测是 commodity商品的缩写负责商品表的增删改查crDAO.class 通常对应 comment/rating评价的数据操作File.class 则是上传文件的封装工具类。从命名就能看出来这个系统至少拆成了“商品管理”和“评价管理”两条数据链路符合 JSP 课程设计最常见的分工。文件推测职责说明SmartUpload.class文件上传组件处理商品图片上传ComDAO.class商品数据访问对象商品增删改查crDAO.class评价数据访问对象评分与评论的数据库操作File.class上传文件工具类保存上传文件、生成路径*.bmp商品图片素材页面展示用这里要泼一盆冷水压缩包里没有展开 JSP 源码直接改业务逻辑是不可能了。但 class 文件不是黑匣子后面我会演示用 javap 和 CFR 把关键类还原成可读代码。如果只是做毕业设计演示部署起来跑通功能就够了如果真要改功能就得先走一遍反编译流程。2.2 JSP 处理商品与评价请求的 MVC 链路一个典型的请求路径是这样的浏览器里的 JSP 页面通过表单或超链接发起请求Servlet 接收参数调用 DAO 操作数据库最后把结果放回 request 或 session再转发回 JSP 展示。这个项目没有 Spring是标准的 JSP Servlet JDBC 时代产物好处是每一条链路都很直白适合教学。我用一个简化版 Servlet 代码来说明 DAO 在里面的位置。实际 class 里的方法签名可能略有不同但大体结构是类似的WebServlet(/commodity) public class CommodityServlet extends HttpServlet { private ComDAO comDAO new ComDAO(); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String action request.getParameter(action); if (add.equals(action)) { String name request.getParameter(name); String price request.getParameter(price); comDAO.insertCommodity(name, price); response.sendRedirect(commodityList.jsp); } else if (delete.equals(action)) { int id Integer.parseInt(request.getParameter(id)); comDAO.deleteCommodity(id); response.sendRedirect(commodityList.jsp); } } }这段代码体现了 MVC 里的 Controller 角色。Servlet 只做了三件事收参数、调 DAO、跳页面。业务逻辑全部藏在 ComDAO 里这也就是为什么 ComDAO.class 是这个项目的核心。参数 action 决定了走新增还是删除name、price 对应商品字段。实际这个系统可能还包含 edit、update 等分支但套路一致。理解这条链路之后再去看 claSS 文件心里就有底了——ComDAO 是商品管理的“数据库翻译官”crDAO 则是评分统计的“计算器”。2.3 商品评价系统的数据库表设计最少三张表从功能反推这个系统最少需要三张表商品表、评价表、管理员表。商品表存商品名称、价格、库存、图片路径评价表存用户对某个商品的评分、评论内容、评价时间管理员表存登录账号和密码。有些版本还会加一个用户表如果只允许“浏览者”评分而不区分具体用户那就在评价表里存一个用户名或 session 标识即可。为了让你能直接初始化我给出一个兼容 MySQL 5.7 的建表脚本CREATE DATABASE IF NOT EXISTS shop_db DEFAULT CHARSET utf8mb4; USE shop_db; CREATE TABLE tb_commodity ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, price DECIMAL(10,2) DEFAULT 0, stock INT DEFAULT 0, image VARCHAR(255), description TEXT ); CREATE TABLE tb_comment ( id INT PRIMARY KEY AUTO_INCREMENT, commodity_id INT NOT NULL, username VARCHAR(50), score TINYINT DEFAULT 5, content VARCHAR(500), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (commodity_id) REFERENCES tb_commodity(id) ); CREATE TABLE tb_admin ( id INT PRIMARY KEY AUTO_INCREMENT, admin_name VARCHAR(50) UNIQUE, password VARCHAR(50) ); INSERT INTO tb_admin (admin_name, password) VALUES (admin, 123456);商品表 id 是主键price 用 DECIMAL 而不是 DOUBLE是为了避免精度问题。评价表 commodity_id 作为外键score 用 TINYINT 限制在 0 到 127足够存 1 到 5 星。create_time 默认当前时间这样插入时不用手动传时间。管理员表先塞一个 admin / 123456方便第一次登录。这块要注意如果资源包本身带了 .sql 文件优先用压缩包里的表名和字段因为 class 里的 SQL 语句是写死的。我给的这份脚本是基于功能推断的“通用结构”万一 ComDAO 里查的是 goods 表你就得调整表名后面会讲怎么从 class 里搜字符串常量来确认。2.4 部署环境选型Tomcat 8.5 MySQL 5.7 的理由老 JSP 项目最怕环境太新。Tomcat 10 把 javax.servlet 包名换成了 jakarta.servlet这个项目里的 class 是用旧包名编译的直接扔进 Tomcat 10 会报 NoClassDefFoundError。Tomcat 9 还在用 javax但有些早期项目用了过时的 JDBC 驱动在 Tomcat 9 高版本上也能跑。我个人习惯用 Tomcat 8.5兼容性最稳妥。JDK 用 1.8因为这个阶段的课程设计大多在 JDK 8 下编译用新 JDK 跑旧 class 会报 UnsupportedClassVersionError。数据库方面MySQL 5.7 是首选。MySQL 8 的默认认证插件是 caching_sha2_password老版本的 mysql-connector-java 5.x 连上去会报认证失败。如果你电脑里已经装了 MySQL 8也不是完全不能跑但要下载 mysql-connector-java 8.0.x并把连接串加上 allowPublicKeyRetrievaltrue 和 useSSLfalse。这个细节很琐碎但能不能起来全靠它。把环境版本定下来后面所有操作就都围绕这套组合展开。版本太新不是好事代码里写死的 JDBC 连接方式不会自己适应新版本能用稳定组合跑通演示就已经成功了一大半。3. 把 star.zip 跑起来从 Tomcat 到 MySQL 的逐步落地3.1 解压与目录放置先看清 Tomcat 的 webapps 规则压缩包解压之后不要直接双击 class 文件那没有任何意义。Tomcat 部署的是整个 web 目录你要做的是把解压后的文件夹放到 webapps 下面。如果压缩包本身是某个 web 项目目录打包的解压后应该能看到 WEB-INF 文件夹如果只看到了散落文件就手动新建一个项目目录再放进去。我一般这样操作mkdir -p ~/star_app unzip star.zip -d ~/star_app # 假设解压出来的文件名是 star则移动到 Tomcat webapps mv ~/star_app/star /opt/tomcat/webapps/这段命令里unzip -d 指定了解压目标目录避免文件散落到当前目录。mv 把项目文件夹放进 webapps 后Tomcat 启动时会自动部署 war 或目录。如果项目里有 WEB-INF/web.xml那么访问路径通常是 http://localhost:8080/star/如果没有 web.xml就需要看有没有 index.jsp 或 servlet 注解。这里有个常见陷阱文件夹名字决定访问路径所以 star 这个名字尽量保留。改名会导致静态资源里的相对路径全部变成 404这是我踩过的坑。解压完成后先不要急着启动下一步把数据库准备好。3.2 数据库初始化建库建表与默认账号数据库连接信息通常写在某个配置文件里比如 db.properties、jdbc.properties 或者干脆硬编码在 ComDAO.class 里。在启动前先按第 2 章给出的 SQL 建库建表并确认账号密码。如果项目里已经带了数据库脚本就用自带的没有的话才用推断的脚本。我用 MySQL 客户端执行建库脚本mysql -uroot -p init_db.sql执行成功后再手动查一下表是否存在USE shop_db; SHOW TABLES;这一步属于“提前验证”。很多同学直接启动 Tomcat结果日志里报 SQL 语法错误回头才发现表没建。先跑一遍建表 SQL能避免把时间浪费在排查数据库连接上。注意如果 class 里的 SQL 硬编码了表名比如 tb_goods那你就要把上面脚本里的表名改成 tb_goods否则运行时一样报找不到表。3.3 数据库连接配置从 class 里找 jdbc.properties 的常见套路这个资源的文件清单里没有暴露 .properties 文件但 JSP 项目通常会把数据库连接放在 WEB-INF/classes 目录下或者由 DBUtil.class 加载一个配置文件。因为压缩后只看到了部分文件所以我们要先检查项目目录结构。在 Linux 或者 Windows 命令行下执行cd ~/star_app/star find . -name *.properties -o -name *.xml -o -name *.txt | head -20如果找到 db.properties打开后大概率长这样drivercom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/shop_db?useUnicodetruecharacterEncodingUTF-8 usernameroot password123456这里 driver 使用的是老驱动包 com.mysql.jdbc.Driver对应 mysql-connector-java 5.x。如果你用的是 MySQL 8要把 driver 改成 com.mysql.cj.jdbc.Driver并且 url 里追加 serverTimezoneAsia/Shanghai。改完配置后还要确认 WEB-INF/lib 目录下有对应的 mysql-connector jar 包。这个 jar 不会凭空出现没有的话去下载一个文件名类似 mysql-connector-java-5.1.49.jar 或 8.0.33.jar。如果你的 find 命令什么都没找到那说明连接配置硬编码在 ComDAO.class 里了。这种情况先别急着改先去运行系统如果报错再考虑反编译。我在第 6 章会给出反编译命令硬编码的 url 和账号能从字符串常量里提取出来。3.4 启动 Tomcat 与验证首页数据库准备好、配置文件确认过就可以启动 Tomcat 了。干净启动方式是在 Tomcat 根目录下运行 startup.sh注意别在 webapps 目录里执行否则会找不到 catalina 脚本cd /opt/tomcat/bin ./startup.sh tail -f ../logs/catalina.out看到 “Server startup in [多少毫秒]” 基本就说明部署成功。如果日志里出现 “SEVERE: Exception starting filter” 或者 “ClassNotFoundException”优先检查 WEB-INF/lib 下是不是缺 jar 包。启动成功后浏览器访问http://localhost:8080/star/index.jsp如果端口不是 8080去 conf/server.xml 里看 Connector 的 port。首页如果出来了说明 JSP 引擎能编译页面class 文件也加载成功。接下来不要急着欢呼把管理员登录和商品列表都点一遍才算真正验证完。因为很多项目首页能显示静态内容但一涉及数据库就报错后面一章专门讲功能链路验证。4. 功能验证商品管理与评分链路到底怎么走4.1 管理员登录与商品管理请求数据流系统能打开首页只是第一步真正要验证的是“管理员登录 → 新增商品 → 评价商品”这条完整链路。老式 JSP 系统登录一般用 session 记录登录状态登录成功后在 session 里放一个标记比如 adminId。后面每次操作后台页面时JSP 再检查 session 是否为空。如果不为空才能看到管理菜单否则直接跳回登录页。我在没有源码的情况下一般先用浏览器登录一次再打开浏览器的开发者工具看请求参数。假设登录页表单字段是 adminName 和 password对应的请求是这样的POST /star/adminLogin.jsp?actionlogin adminNameadminpassword123456如果能成功跳转到 admin_main.jsp说明 session 写入逻辑通了。接着测试新增商品。打开商品管理页表单里的字段大概率是 name、price、stock、imageFile。其中 imageFile 是文件输入框交给 SmartUpload 处理。提交后去数据库里查一条记录SELECT * FROM tb_commodity ORDER BY id DESC LIMIT 1;查到了说明 ComDAO 的 insert 方法正常。查不到先看页面是不是报 500再看 catalina.out 里有没有 SQL 异常。新增商品是评价系统的前提这一步不通后面都不用测。4.2 用户评分与平均分更新的业务规则评价模块的设计通常有两种一种是在评价表新增一条记录然后实时计算平均分另一种是商品表里维护一个 rating_avg 字段每次评价都更新。前面我给的表结构是第一种因为 crDAO 这个名字更接近“评论”数据操作。平均分的计算逻辑一般放在 DAO 里。因为 class 文件里是编译后的字节码我直接描述常见实现查询 tb_comment 里该商品所有 score 的 SUM 和 COUNT然后 SUM / COUNT 得到平均分。如果还想查最新评论就按 create_time DESC 排序。这段逻辑用 SQL 表达是下面这样SELECT commodity_id, AVG(score) AS avg_score, COUNT(*) AS comment_count FROM tb_comment WHERE commodity_id 1 GROUP BY commodity_id;AVG 函数处理的是 TINYINT 类型的 score返回结果是 DECIMAL在 Java 里拿 BigDecimal 接收比较稳妥。要注意的是如果项目在商品表里冗余了 avg_score 字段那上面的 SQL 只是查询真正的逻辑还得看 crDAO 里的 update 调用。但无论哪种业务核心都是“得分总和除以评价次数”。4.3 用 curl 走一遍评价提交没有前端源码的时候用 curl 模拟请求是验证后端最直接的手段。先登录拿到 session cookie再带着 cookie 提交评价。这里假设评价提交的 URL 是 comment.jsp参数是 commodityId、score、content。# 先登录把 cookie 保存到文件 curl -c cookies.txt -d adminNameadminpassword123456 \ http://localhost:8080/star/adminLogin.jsp # 模拟评分请求 curl -b cookies.txt \ -d commodityId1score5content非常满意 \ http://localhost:8080/star/comment.jspcurl -c 的作用是保存服务器返回的 Cookie-b 是使用之前保存的 Cookie。如果页面前端还有 JS 校验这种方式可能会被拦截。拦截了也不用慌打开浏览器控制台找到 Network 面板里实际发出的请求照着请求的路径和参数再改一次。提交完成后去数据库查 tb_comment能看到刚刚插入记录说明整条评价链路是通的。4.4 评价列表的分页与排序规则评价列表通常在商品详情页下方展示所有用户对该商品的评论。老项目分页很喜欢用 limit 加页码的方式。URL 上的参数可能是 pageIndex 和 pageSize比如 pageIndex1pageSize10。对应 SQL 是SELECT c.*, a.username FROM tb_comment c LEFT JOIN tb_admin a ON c.username a.admin_name WHERE c.commodity_id ? ORDER BY c.create_time DESC LIMIT ?, ?;这里 LEFT JOIN 只是为了把用户名显示出来如果你当初设计时没有用户表就直接查 tb_comment。LIMIT 的第一个问号是偏移量用 (pageIndex - 1) * pageSize 计算第二个问号是每页条数。注意 LIMIT 的偏移量不能用字符串拼接要 NumberFormat 转成 int否则 SQL 注入和类型错误都会出现。分页功能能否用也是检验系统品质的重要参考。5. 部署与运行避坑class 项目最容易翻车的五个细节5.1 数据库连接失败驱动加载与实际连接串现象Tomcat 启动后访问管理页面页面报 500catalina.out 里出现 “Cannot create PoolableConnectionFactory” 或 “Access denied for user”。原因绝大多数是 mysql-connector jar 版本和 MySQL 版本不匹配。老连接串写成 jdbc:mysql://localhost:3306/shop_db没带 useSSL 和 serverTimezoneMySQL 8 的驱动会直接拒绝连接。解决先确认 jar 版本再改连接串。MySQL 5.7 用 mysql-connector-java-5.1.49MySQL 8 用 8.0.33并把 url 改成urljdbc:mysql://localhost:3306/shop_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingUTF-8如果是用户名密码错误那就去 MySQL 里重置 root 密码或者新建专用账号。连接串这种事改错一个字符就是半天最好把当前配置复制出来只替换参数值不要手动重敲整个 url。5.2 图片上传失败SmartUpload 的目录陷阱现象管理员新增商品时文字信息能保存但选择商品图片后点击提交页面报 “The request contains a multipart/form-data stream which is corrupted” 或者后台找不到保存路径。原因SmartUpload 类要求上传目录已经存在。很多 JSP 项目把图片保存到 upload 目录但打包时没有保留空目录Tomcat 部署后 upload 文件夹根本不存在SmartUpload 往里写文件时就抛异常。解决在项目根目录下手动创建 upload 文件夹确保 Tomcat 运行用户有写权限。在 Linux 下执行mkdir -p ~/star_app/star/upload chmod 777 ~/star_app/star/upload同时检查保存路径是相对路径还是绝对路径。如果是 /upload那会指到系统根目录下正确做法是写成相对路径 upload 或者用 request.getRealPath(upload) 获取应用真实路径。上传成功后还要看文件名是否有中文老组件对中文文件名支持很差最好在代码里重新生成文件名。5.3 bmp 图片在浏览器里无法显示现象商品列表页能展示文字但图片位置是个空白的破损图标。打开开发者工具发现 img 标签的 src 指向 .bmp 文件浏览器拒绝显示。原因bmp 格式虽然是微软的标准位图格式但除了 IE 和少数浏览器现代浏览器基本不直接支持 bmp 内联显示。项目提供的素材偏偏全是 bmp自然就全部空白。解决把 bmp 统一转换成 jpg 或 png。不需要改代码直接用格式转换工具批量转没有工具的话用 ImageMagickfor f in ~/star_app/star/*.bmp; do convert $f ${f%.bmp}.jpg done转换后记得把数据库里 image 字段的值和页面 img 标签的路径改成 .jpg。如果页面是直接从数据库里读 image 路径那只需要改数据库记录如果页面上一开始就写死了 .bmp就必须去改 JSP 文件。这也是 class 资源的一个麻烦点改完图片路径没生效时优先怀疑浏览器缓存。5.4 中文乱码从请求编码到数据库编码不一致现象新增商品时输入“洗衣机”保存后数据库里显示“ϴϴ”或“???”评价内容里的中文也全部乱码。原因这是老项目最经典的问题。JSP 页面用 GBK 编码提交数据库字段用 utf8mb4Tomcat 的 URIEncoding 默认又不是 UTF-8三层编码不一致中文就废了。解决三层统一改成 UTF-8。首先是数据库连接串加 characterEncodingUTF-8其次是修改 Tomcat 的 conf/server.xml在 Connector 上加上 URIEncodingUTF-8最后在 JSP 页面头部加 % page contentTypetext/html; charsetUTF-8 %。如果这三个地方都已经统一还是乱码那就去 server.xml 里找 useBodyEncodingForURI 参数把它设为 true。这种乱码问题排查起来最烦因为它不会报错只会显示一堆看不懂的字符我每次部署老项目都会先把编码全部改完再启动。5.5 Tomcat 与 JDK 版本导致的 class 版本不兼容现象Tomcat 启动后在日志中看到 “UnsupportedClassVersionError: ComDAO has been compiled by a more recent version of the Java Runtime”后台某个功能直接 500。原因class 是由比当前 JDK 更高版本编译出来的。比如项目编译于 JDK 11而你本地跑的是 JDK 8JVM 无法加载高版本字节码。解决切换到更高版本的 JDK 运行 Tomcat。在 startup.sh 前面手动指定 JAVA_HOME 是最快的办法export JAVA_HOME/path/to/jdk11 export PATH$JAVA_HOME/bin:$PATH cd /opt/tomcat/bin ./startup.sh这里路径要换成你自己机器上的 JDK 安装目录。如果不知道 class 到底是哪个版本编译的用 javap -verbose 看 major version52 对应 Java 855 对应 Java 1155 及以上就不要再尝试 JDK 8 了。这个坑通常发生在你从别人那里拿到的课程设计资源里对方电脑是 JDK 11 或 17不统一就只能换运行时。6. 进阶用 javap CFR 把 class 还原成可维护源码先别急着只把它当一个黑盒跑通你迟早会遇到改功能的需求。这时候 CTRLC 复制粘贴不是出路用工具从 class 里还原源码才靠谱。第一步是用 javap 看类签名这一步在 JDK 自带的工具里就能做javap -p -c ~/star_app/star/WEB-INF/classes/ComDAO.class-p 显示 private 成员-c 打印方法体字节码。javap 输出的是 JVM 指令比如 getfield、invokevirtual对还原字段名和 SQL 字符串特别有用。你会在这里看到类似 “SELECT * FROM tb_commodity” 这种硬编码字符串把它抄出来再去完善建表脚本。但这只能算“看门道”要真正变成 Java 代码用 CFR 更合适。java -jar cfr.jar ~/star_app/star/WEB-INF/classes/ComDAO.class --outputdir ./srcCFR 会把 ComDAO.class 反编译成近乎可以重新编译的 Java 文件DAO 方法的参数名、循环、SQL 拼接全都能看到。反编译出来的代码质量虽然不如原版但用于理解逻辑和移植重写完全够用。拿到还原后的 ComDAO我通常会把硬编码的数据库连接抽到 db.properties把 JDBC 资源释放写成 try-with-resources再把项目按 Maven 目录结构重新组织一遍。从那以后我每次遇到只有 class 和图片的老项目都会强制走一遍“先部署验证再反编译看核心 SQL最后抽取配置”这个流程确认系统边界在哪、哪些字段不能动、哪些逻辑是硬编码的再决定要不要继续往下改。希望这篇记录帮你在 star.zip 上少走几步弯路把商品管理和评价系统真正变成你能控制的东西。本文还有配套的精品资源点击获取
返回列表