ARTICLE DETAIL

资讯详情

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

JSP在线洗衣店管理系统源码解析与部署避坑指南

JSP在线洗衣店管理系统源码解析与部署避坑指南 简介JSP在线洗衣店管理系统是一套面向Java Web学习者的完整项目源码适用于课程设计或毕业设计场景。系统按管理员、会员、员工三种角色划分功能模块管理员可进行员工管理、洗涤价格设置、收益查询及会员注销用户可在线选择干洗衣物、提交订单、充值余额员工则负责洗涤记录的登记与维护基本覆盖了洗衣店日常运营的核心流程。压缩包共48个文件以21个Java源文件、14个JSP页面和8个TLD标签描述文件为主附带配置属性文件与说明文档整体仅56KB结构轻量且目录清晰便于在Tomcat等环境下快速部署与二次开发。已有117人学习过这套代码适合希望掌握JSPServletJavaBean开发模式、理解多角色权限管理实现的读者。通过研读源码可以学到表单交互、会话跟踪、数据库操作及标签库使用等实用技巧也能直接在此框架上扩展新功能是一份适合反复琢磨的入门级实战项目。1. 打开这个zip的人十有八九在赶Java课程设计JSP在线洗衣店管理系统源码.zip这个文件名对两类人特别有吸引力一类是正在做Java课程设计的在校生另一类是想接私活但不想从零写管理后台的初级工程师。打开之后你会发现它其实是一个典型到不能再典型的Java Web课题——JSP做页面、Servlet做控制、MySQL存数据业务上覆盖了用户注册登录、衣物下单、价格计算、订单状态流转、后台管理这几个模块。它不是什么高并发分布式系统但恰好是能把JavaWeb知识串起来的最小完整闭环。这篇笔记不讨论怎么把代码吹成生产级平台而是讲清楚怎么把它跑起来、读懂订单这条核心链路、以及那些让课设项目在演示当天翻车的细节。2. 先看懂JSP在线洗衣店管理系统的牌面分层结构与三张核心表2.1 为什么这种老技术栈反而适合当课设很多新手拿到这个源码包第一反应是“JSP不是过时了吗”然后想换成Spring Boot重写。我劝你别急。JSP在线洗衣店管理系统这类老项目价值恰恰在于代码足够直白没有Spring IoC容器帮你把对象注入得神不知鬼不觉没有MyBatis的Mapper代理把SQL藏得严严实实。你能直接看到request.getParameter()拿到表单值再用Class.forName()加载JDBC驱动手动PreparedStatement拼SQL最后out.println()回写页面。这个过程虽然笨但每一步都在训练你理解HTTP请求生命周期和数据库连接的生命周期。而且从课程设计的评分标准来看JSP课设一般看三个维度功能完整度、数据库设计合理性、代码结构清晰度。洗衣店管理系统天然具备完整的业务链条不是那种随便糊一个CRUD就完事的玩具。常见的模块划分是前台用户模块注册、登录、浏览服务、下单、后台管理模块订单审核、状态更新、价格维护、会员模块充值、余额扣减。这三块合起来正好覆盖了一个管理系统最常见的权限分层思路。技术选型上这套系统一般沿用JSP Servlet JavaBean MySQL的经典组合有的版本会引入JSTL标签库减少Java脚本碎片。如果你拿到手的源码里看到% taglib urihttp://java.sun.com/jsp/jstl/core prefixc %说明作者至少做了页面表现层和业务逻辑层的分离。没有也没关系那种直接在JSP里写% if(session.getAttribute(user) ! null) %的代码虽然丑但更好调试。2.2 用户表与会员卡注册、余额、等级怎么落表洗衣店管理系统里用户不只是“账号密码”这么简单因为业务里牵扯到充值、折扣、订单归属。常见的做法是一张tb_user用户表加一张tb_member会员表两者通过用户ID关联。用户表存放账号密码、手机号、注册时间、状态会员表存余额、积分、等级、办卡时间。这种拆分的好处是非会员也能下单但享受不了折扣和余额支付符合真实洗衣店“会员制”运营逻辑。建表SQL通常长这样我加了一些索引和默认值CREATE TABLE tb_user ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录名, password VARCHAR(64) NOT NULL COMMENT 密码建议MD5后存储, phone VARCHAR(11) DEFAULT NULL COMMENT 手机号, status TINYINT DEFAULT 1 COMMENT 1正常 0禁用, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; CREATE TABLE tb_member ( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL COMMENT 关联tb_user.id, balance DECIMAL(10,2) DEFAULT 0.00 COMMENT 账户余额, points INT DEFAULT 0 COMMENT 积分, level TINYINT DEFAULT 1 COMMENT 1普通 2银卡 3金卡, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_user_id (user_id), CONSTRAINT fk_member_user FOREIGN KEY (user_id) REFERENCES tb_user(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT会员表;这两个表的关键参数在注释里已经标了。密码用MD5是这套老代码的默认做法放在今天只能算“最低安全要求”但课设答辩时你能说出“不能明文存密码”这句话已经加分了。DECIMAL(10,2)存金额而不是FLOAT是因为浮点数在二进制下无法精确表示0.1洗衣价格虽小但累计下来会出账目误差。外键约束fk_member_user保证了一个用户最多一条会员记录避免程序里二次判断。2.3 衣物类型表价格计算的源头洗衣店的计价模式一般两种按件计费和按重量计费。这套系统的源码里大多数实现是“按件计费”所以一定有一张衣物类型表存着每类衣物的基础价格。衬衫洗一件多少钱、羽绒服洗一件多少钱、毛毯是不是需要特殊处理全部在这张表里配置。CREATE TABLE tb_clothes_type ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 衣物类型ID, type_name VARCHAR(50) NOT NULL COMMENT 衣物名称如衬衫/羽绒服/毛毯, unit_price DECIMAL(10,2) NOT NULL COMMENT 标准洗护单价, discount_price DECIMAL(10,2) DEFAULT NULL COMMENT 会员价NULL表示不打折, icon_path VARCHAR(255) DEFAULT NULL COMMENT 衣物图片路径, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT衣物类型价格表;这张表的使用场景很直接用户在前台勾选“衬衫2件、羽绒服1件”后台根据衣物类型ID查询单价数量乘以单价得到总价。如果用户是会员还要判断discount_price字段是否有值有值就走会员价。这个逻辑如果看不懂源码自己去PriceService或OrderServiceImpl这种类里搜discount_price字段名基本一眼定位。icon_path在做前台展示时会起到作用但这会在第五章的图片路径问题里讲这里先记住它是相对路径还是绝对路径。2.4 订单表整个系统的业务主表订单表是洗衣店管理系统的核心几乎所有页面都在围绕它转。用户下单插入一条订单后台管理员修改订单状态用户查询订单状态统计营业额也来自这张表。字段设计上至少要包含订单编号、用户ID、衣物类型ID、数量、总金额、下单时间、取件时间、状态、备注。CREATE TABLE tb_order ( id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL UNIQUE COMMENT 订单编号格式YYYYMMDDHHMMSS随机数, user_id INT NOT NULL COMMENT 下单用户ID, clothes_type_id INT NOT NULL COMMENT 衣物类型ID关联tb_clothes_type, quantity INT DEFAULT 1 COMMENT 件数, total_price DECIMAL(10,2) NOT NULL COMMENT 订单总金额, status TINYINT DEFAULT 0 COMMENT 0待取件 1洗涤中 2待取回 3已完成 4已取消, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 下单时间, finish_time DATETIME DEFAULT NULL COMMENT 完成时间, remark VARCHAR(255) DEFAULT NULL COMMENT 备注如特殊污渍处理, INDEX idx_user_id (user_id), INDEX idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单表;这里的核心参数是status字段我用注释明确限制了取值范围。老代码里混乱的点在于不同版本的项目对状态码定义不一样有的用字符串“已下单/进行中/已完成”有的用TINYINT。如果你拿到手的源码里状态定义和我的注释不一致不要慌先去OrderDAO里看查询条件或者前台JSP页面的下拉框选项就能反推出作者定义的状态机。order_no生成规则通常是SimpleDateFormat拼上Math.random()实际开发中应该用更严格的唯一ID生成器但课设里不深究。total_price在订单表里冗余存储这是故意设计的——因为衣物价格表可以改价如果订单不冗余存储成交价改价后统计口径就乱了。3. 把源代码跑起来从环境匹配到Tomcat部署3.1 版本不是越新越好JDK 8 Tomcat 8.5 MySQL 5.7 的搭配理由很多人拿到源码第一步就卡在环境上。我见过太多案例装了JDK 17项目编译直接报javax.servlet包不存在装了Tomcat 10启动后Servlet加载直接500。原因很简单JSP课设源码诞生年代决定它依赖的是javax.*命名空间而Tomcat 10以后把API换成jakarta.*旧代码直接废掉。所以我强烈建议用JDK 8 Tomcat 8.5 MySQL 5.7这个组合跑老项目没有兼容性烦恼网上遇到的报错也基本都能搜到答案。具体版本对照组件推荐版本理由JDK1.88u211以上JSP课设标准编译环境兼容性天花板Tomcat8.5.x支持javax.servlet稳定且文档多MySQL5.7.x避免8.x的密码加密插件兼容坑也够用mysql-connector-java5.1.49适配MySQL 5.7Class.forName驱动加载无压力Eclipse IDE2020-06及以上JSP插件内置开箱即用有同学问能不能用IntelliJ IDEA当然能但注意社区版不带Web运行配置你得手动配置Tomcat Server或使用Maven插件。如果嫌麻烦Eclipse的Dynamic Web Project对老项目支持最省心。连接数据库时如果换用MySQL 8.x也不是不行但你必须在JDBC URL后面加上allowPublicKeyRetrievaltrueuseSSLfalse这个参数我在第五章会专门讲属于必踩的坑。3.2 导入源码并改好三个配置文件假设你已经解压了JSP在线洗衣店管理系统源码.zip在Eclipse里File - Import - Existing Projects into Workspace导入后先别急着运行你得先检查三个文件。这三个文件是Web项目的生命线src/db.properties数据库连接、src/filter/CharacterFilter.java编码过滤、WebContent/WEB-INF/web.xmlServlet映射。先看数据库配置文件# 数据库连接配置 jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/laundry_db?useUnicodetruecharacterEncodingutf8 jdbc.usernameroot jdbc.password123456这里的参数是踩坑重灾区。characterEncodingutf8必须和数据库实例的字符集一致如果MySQL建库时用了utf8mb4这里用utf8在插入生僻字符时可能报错建议直接改成characterEncodingutf8mb4MySQL驱动5.1.47以后支持这个写法。密码字段按你本地实际情况改。如果项目里用的是c3p0连接池那么还存在一个c3p0-config.xml里面的jdbcUrl参数改法一样的。再看web.xml里的编码过滤器配置这是中文乱码的第一道防线filter filter-nameCharacterFilter/filter-name filter-classcom.laundry.filter.CharacterFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameCharacterFilter/filter-name url-pattern/*/url-pattern /filter-mappingurl-pattern配成/*表示所有请求都经过这个过滤器。如果你的CharacterFilter类不存在说明源码里没写编码过滤器那你必须自己补一个否则POST请求里的中文必乱。补这个类的方式我在第五章第一条避坑里写。3.3 发布到Tomcat与第一次访问验证Eclipse里右键项目名Run As - Run on Server选择你配置好的Tomcat 8.5等控制台出现Server startup in [xxxx] milliseconds就说明启动成功。如果你习惯直接用Tomcat的webapps目录部署另一种做法是把项目打包成WAR# 进入项目根目录执行打包需要已配置Maven mvn clean package -DskipTests # 或者没有Maven时用Eclipse导出WAR # 右键项目 - Export - WAR file # 将生成的war包拷贝到Tomcat的webapps目录 cp target/laundry.war /path/to/tomcat/webapps/ # 启动Tomcat cd /path/to/tomcat/bin ./startup.sh启动后浏览器访问http://localhost:8080/laundry/如果看到登录页面说明部署成功。注意项目访问路径不是http://localhost:8080/而是带项目名laundry。如果你把WAR包改名为ROOT.war部署后才可以不带项目名访问。这一步有一个很隐蔽的坑如果改名为ROOT.war之前Tomcat已经解压出了ROOT文件夹旧文件夹不会自动清除需要手动删除再启动否则你看到的一直是旧版本的页面。第一次访问容易出黑屏500错误的场景大多和数据库没连上相关。用浏览器开发者工具F12看Network面板如果请求状态码是500去Tomcat的logs/localhost.2024-xx-xx.log里翻Caused by它下面跟着的异常信息才是根因。4. 读源码先读链路订单状态机与价格计算怎么落地4.1 订单状态从下单到取衣的状态扭转JSP在线洗衣店管理系统的业务核心不在页面样式而在订单从创建到完结的状态推进。搞清楚状态机流转你就能理解和修改几乎所有核心逻辑。通常这套系统的状态流转是用户提交订单状态0待取件→ 洗衣店上门取件状态1洗涤中→ 洗涤完成状态2待取回→ 用户取回衣服状态3已完成。此外有一个非主线状态4已取消用于用户下单后反悔或超时未取件。状态机代码一般封装在OrderService里核心方法长这样public boolean updateOrderStatus(int orderId, int targetStatus) { // 校验状态流转是否合法 int currentStatus orderDao.getStatusById(orderId); if (!canTransit(currentStatus, targetStatus)) { throw new IllegalStateException(非法的订单状态流转: currentStatus - targetStatus); } String sql UPDATE tb_order SET status ? WHERE id ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, targetStatus); ps.setInt(2, orderId); int rows ps.executeUpdate(); if (rows 1 targetStatus 3) { // 订单完成时记录完成时间 updateFinishTime(orderId); } return rows 1; } catch (SQLException e) { e.printStackTrace(); return false; } } private boolean canTransit(int current, int target) { // 状态流转规则表只允许向相邻状态推进或取消 if (current 0 (target 1 || target 4)) return true; if (current 1 target 2) return true; if (current 2 target 3) return true; return false; }参数说明currentStatus从数据库读出来targetStatus由管理员页面下拉框提交。canTransit方法是你要重点理解的地方它把状态规则集中在一处管理避免在多个JSP页面里各写一套判断。如果你拿到的源码里没有这种校验方法而是直接在页面写死按钮的显示逻辑那说明这个项目状态控制是靠前端兜底——管理员的JSP页面里c:if test${order.status 0}控制显示哪个按钮后端几乎没有校验。这种实现的风险在于恶意请求可以直接构造参数跳过流程课设答辩时你能指出这一点反而是加分项。状态机的另外一层应用是首页订单列表的展示。用户登录后看到自己的订单每个订单的状态描述不能直接显示数字“0/1/2”必须映射成中文描述。这一步一般放在Order.java实体类的getStatusText()方法里实现用switch语句把数字转换成“待取件/洗涤中/待取回/已完成/已取消”。4.2 价格计算的服务层代码实体关系、会员折扣和金额计算价格计算是整个系统里最容易做错业务逻辑的地方。常见实现是把价格计算放在OrderServiceImpl里用户选择衣物后根据衣物类型ID查出单价判断当前用户是不是会员是会员再看tb_clothes_type表里discount_price是否为NULL然后用会员价计算最后乘以数量并写入订单表。public double calculateTotalPrice(int clothesTypeId, int quantity, int userId) { ClothesType type clothesTypeDao.findById(clothesTypeId); if (type null) { throw new RuntimeException(衣物类型不存在); } // 基础价格 单价 * 数量 double unitPrice type.getUnitPrice(); // 查询用户会员等级会员且衣物类型配置了会员价时使用会员价 Member member memberDao.findByUserId(userId); double finalUnitPrice unitPrice; if (member ! null type.getDiscountPrice() ! null) { finalUnitPrice type.getDiscountPrice(); } // 积分抵扣100积分抵1元最多抵扣订单金额的10% double rawAmount finalUnitPrice * quantity; double maxDeduct rawAmount * 0.10; double deduct Math.min(member null ? 0 : member.getPoints() / 100, maxDeduct); return rawAmount - deduct; }参数说明clothesTypeId是用户在页面下拉框选中的衣物类型主键quantity是件数userId从当前会话session.getAttribute(userId)里取。代码里做了明显的边界处理会员为NULL时不会走会员价discountPrice为NULL时也不会NPE。积分抵扣这部分不是每个项目都有如果你的源码里没有积分逻辑直接忽略这段。这部分代码里还有一个你没注意到但很重要的细节金额计算用double会有精度误差比如0.1 0.2 0.30000000000000004。如果项目要求金额精确到分应该把所有金额计算换成BigDecimal。但这个改动工程量大课设项目里用double是普遍现象。你可以在答辩备注里写“已知问题金额采用double存在精度误差生产环境应替换为BigDecimal”这种自曝短板的做法在黑盒评审里反而显示你懂行。4.3 JSP页面怎么把订单状态渲染出来前两节讲的是后端处理逻辑这一节要落到JSP页面上。在线洗衣店系统的前台查询订单列表一般用JSTL的c:forEach循环订单集合然后用c:if判断状态值。代码示例如下% taglib urihttp://java.sun.com/jsp/jstl/core prefixc % table border1 tr th订单编号/th th衣物/th th数量/th th金额/th th状态/th th操作/th /tr c:forEach items${orderList} varorder tr td${order.orderNo}/td td${order.clothesTypeName}/td td${order.quantity}/td td¥${order.totalPrice}/td td c:choose c:when test${order.status 0}待取件/c:when c:when test${order.status 1}洗涤中/c:when c:when test${order.status 2}待取回/c:when c:when test${order.status 3}已完成/c:when c:when test${order.status 4}已取消/c:when /c:choose /td td c:if test${order.status 0} a hreforder?actioncancelid${order.id}取消订单/a /c:if c:if test${order.status 3} a hreforder?actiondetailid${order.id}评价服务/a /c:if /td /tr /c:forEach /table这里用c:choose代替多个c:if是为了避免状态条件的重复匹配JSTL的c:choose是互斥分支。页面里按钮的显示条件也严格跟随状态只有状态0才允许取消只有状态3才显示评价入口。如果你拿到手的源码里同时显示“取消”和“评价”两个按钮说明作者没做状态控制用户体验会错乱。JSP页面里还有个常见问题${order.clothesTypeName}这个属性从哪来如果你看tb_order表里只有clothes_type_id没有clothesTypeName那说明查询订单列表时用了JOIN语句把衣物类型表和订单表关联起来SELECT o.*, c.type_name AS clothesTypeName FROM tb_order o LEFT JOIN tb_clothes_type c ON o.clothes_type_id c.id WHERE o.user_id ?在这个查询里LEFT JOIN是关键参数——它保证订单记录不会因为衣物类型被删除而丢失以订单表为主表。如果你的源码里用的是INNER JOIN那衣物类型一旦被删历史订单在列表页直接消失。5. JSP洗衣系统避坑五条影响跑通的常见问题排查5.1 中文乱码三个地方漏一个就乱现象页面输入中文用户名注册后数据库里存进去是“???”或者页面标题全是“汉嗔。原因JSP页面的编码、Servlet响应编码、数据库连接字符集三个环节只要有一个不是UTF-8中文就保不住。而且GET请求和POST请求的乱码源头还不一样——POST乱码靠过滤器解决GET乱码靠Tomcat的server.xml里配置URIEncoding。解决三个地方逐一固定。第一所有JSP页面头部的contentType改成text/html; charsetUTF-8且pageEncodingUTF-8。第二确保你自己的编码过滤器类存在并生效实现要领如下public class CharacterFilter implements Filter { private String encoding UTF-8; Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(encoding); response.setCharacterEncoding(encoding); chain.doFilter(request, response); } }第三MySQL连接URL里加characterEncodingutf8或utf8mb4同时建库语句里指定DEFAULT CHARSETutf8mb4。三个地方都对了中文乱码基本绝迹。5.2 Tomcat无法启动JDK版本与class version对不上现象Tomcat启动报UnsupportedClassVersionError: xxx has been compiled by a more recent version of the Java Runtime (class file version 55.0)。原因源码是用高版本JDK比如JDK 11编译的而你的Tomcat跑在JDK 8上字节码版本不兼容。解决在Eclipse里右键项目Properties - Java Compiler把编译级别改成1.8然后Project - Clean重新编译。同时保证环境变量里JAVA_HOME指向JDK 8目录不是JDK 17。如果Tomcat启动依然报这个错大概率是Eclipse内置编译器没生效检查Project Facets里Java版本是否同步改到1.8。5.3 数据库连接报错MySQL 8.x的驱动协议坑现象项目用的驱动是com.mysql.jdbc.Driver本地装的是MySQL 8.0运行时抛java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed。原因MySQL 8.x默认使用caching_sha2_password认证插件老驱动5.1.x默认不允许通过RSA公钥传输密码。解决在JDBC URL上追加两个参数完成之后变成jdbc.urljdbc:mysql://localhost:3306/laundry_db?useSSLfalseallowPublicKeyRetrievaltrueuseUnicodetruecharacterEncodingutf8useSSLfalse关闭加密连接开发环境用allowPublicKeyRetrievaltrue允许客户端从服务器获取公钥。如果你用的是com.mysql.cj.jdbc.Driver则要注意驱动类名和URL参数写法都有变化但老项目不建议升驱动保持5.1.49最稳。5.4 部署后页面404项目路径与ROOT混用现象Tomcat启动正常但访问http://localhost:8080/显示404或Tomcat默认首页。原因你的项目没有部署为ROOT所以根路径下没有对应应用。要么把项目打成ROOT.war要么访问http://localhost:8080/项目名/。解决如果想用根路径访问先停掉Tomcat删除webapps/ROOT目录和ROOT.war再把你的WAR包改名成ROOT.war放进去重新启动。注意项目里的绝对路径如果硬编码了/laundry/xxx这种字符串改名为ROOT后这些路径全失效所以更推荐的做法是保持项目名访问别折腾ROOT。页面里所有路径都用%request.getContextPath()%动态拼接才能无论部署在哪个路径都不出问题。5.5 上传的衣物图片不显示路径拼接少了ContextPath现象后台管理上传了一张衣物图片保存成功且Tomcat日志无异常但页面上图片裂开。F12看到图片请求地址是http://localhost:8080/upload/xxx.jpg实际项目路径是http://localhost:8080/laundry/请求到Tomcat根路径当然404。原因JSP页面里用了img srcupload/xxx.jpg这种相对路径方式没有加上项目名。浏览器解析相对路径时是相对于当前页面URL的/laundry/orderList.jsp所以解析成/laundry/upload/xxx.jpg前提是你加了base标签如果用了src/upload/xxx.jpg解析成根路径就直接丢失项目前缀。解决统一改为绝对路径拼接。在JSP页面顶部定义% String basePath request.getScheme() :// request.getServerName() : request.getServerPort() request.getContextPath() /; %然后在img标签里写img src%basePath%upload/xxx.jpg。如果你不想在每个页面都写这段脚本可以用JSTL的c:set或base href%basePath%统一解决。6. 把课设变成能用的系统连接池、防注入与部署细节在线洗衣店管理系统要做到演示不出丑除了跑通以上功能我再送你三件实战级补丁。第一件是数据库连接池。源码里多半是每次请求都Class.forName然后DriverManager.getConnection在演示机器上没问题但一旦多个浏览器标签同时操作MySQL默认连接数很容易被打满。你可以在DBUtil里换成DBCP连接池核心配置就五行BasicDataSource ds new BasicDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/laundry_db?characterEncodingutf8); ds.setUsername(root); ds.setPassword(123456); ds.setMaxTotal(20); // 最大连接数 ds.setMaxIdle(5); // 最大空闲连接数给你的代码说明setMaxTotal(20)意味着系统最多同时打开20个数据库连接超过的连接会排队等待。对课程设计演示场景20完全够用生产环境按并发量调整。升级到连接池后原来那些finally块里手动conn.close()的代码不需要删因为连接池的close()只是归还连接不是真的关闭。第二件是SQL注入的补救。老代码里如果还有直接用Statement执行字符串拼接SQL的地方赶紧改成PreparedStatement// 错误示范字符串拼接SQL // Statement st conn.createStatement(); // st.executeQuery(SELECT * FROM tb_user WHERE username username ); // 正确做法预编译占位符 PreparedStatement ps conn.prepareStatement( SELECT * FROM tb_user WHERE username ? AND password ?); ps.setString(1, username); ps.setString(2, Md5Util.md5(password));第三件是部署到别的机器前把Tomcat的server.xml里连接器加上URIEncodingUTF-8同时把MySQL的my.ini里character-set-serverutf8mb4确认一遍。这两个地方不改你本机一切正常换台电脑演示就中文乱码评选老师看着满屏问号项目再完整也白搭。我之前带过一届实训有个学生拿的就是这个洗衣店项目功能全做完了演示当天在教室电脑上登录页面直接报500原因就是数据库密码写死成他宿舍电脑的密码换了环境忘了改db.properties。所以我现在养成的习惯是任何JSP课设项目收到后第一件事先进db.properties和web.xml把环境相关的配置全部核对一遍再启动而不是急着看代码。这个习惯救过我无数次也希望帮到你。本文还有配套的精品资源点击获取
返回列表