ARTICLE DETAIL

资讯详情

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

基于Servlet+JSP+MySQL的房屋租赁系统:完整业务闭环与避坑指南

基于Servlet+JSP+MySQL的房屋租赁系统:完整业务闭环与避坑指南 简介一套基于Servlet的房屋租赁管理信息系统源码采用Java、Servlet、JSP与MySQL构建面向需要完成Web课程设计、毕业设计或项目实战练习的学习者。系统分为管理员与普通用户两种角色前台包含会员登录注册、忘记密码、新闻中心、出租/求租/出售/求购信息、信息检索、留言板等模块后台覆盖新闻资讯、会员管理、滚动公告、留言板管理、出租出售信息管理以及预定、定金、合同、收付款管理还有房屋统计报表与销售租金报表业务流程完整便于二次开发。资源包共681个文件大小2.6MB主要文件类型为JSP/HTML页面、Java类文件、JS/CSS样式脚本、GIF/JPG图片素材并附带数据库SQL脚本与登录说明完整工程目录结构清晰可直接部署到Tomcat运行。已有262人学习下载适合作为Java Web入门进阶与毕业设计参考。1. 基于 Servlet 的房屋租赁信息系统老技术栈做完整的业务闭环这套基于 Servlet JSP MySQL 的房屋租赁管理系统我拿到后先翻后台菜单出租、求租、出售、求购之外还连着预定、定金、合同、收付款和两张统计报表。很多课程设计做到“能发布房源”就停了这套把成交链路完整接起来了所以它比普通 demo 更适合拿来做毕业设计底座也适合刚学完 Java Web 的人对照着读。项目技术栈是 Java Servlet JSP MySQL要求 JDK1.8、Tomcat7 及以上前端用 JSP、CSS、JavaScript、JQuery、Ajax 做轮播图和异步交互后端由 Servlet 承担控制器。适合两类人一类是想系统梳理前后台完整流程的 Java Web 初学者一类是需要课程设计或毕业设计、愿意在此基础上扩展功能的从业者。下面按环境怎么搭、功能怎么串、代码怎么改、坑在哪里的顺序展开。2. 环境选型与项目导入JDK1.8、Tomcat7、MySQL 的版本组合2.1 技术栈组合为什么我坚持 JDK1.8 Tomcat7项目要求写在最前面JDK1.8、Tomcat7 及以上、MySQL、Eclipse 或 IDEA。这套组合看起来老但它是这个项目风险最低的搭配。Servlet 3.0 时代用的还是 javax.servlet.* 包Tomcat7 对应 Servlet3.0Tomcat8 是 3.1到 Tomcat10 就整体改成 jakarta.servlet.* 了老项目的包名直接编译不过。别小看这个包名差异很多人图新鲜装了 Tomcat10结果项目里每处 import javax.servlet 都报红最后又灰溜溜换回 Tomcat8。MySQL 这边如果跟着大多数安装教程装的是 MySQL5.7直接沿用项目自带的连接驱动就行如果坚持用 MySQL8网上常见的 mysql 8.0.44 安装包就要换新版驱动并处理 SSL 和认证方式问题具体参数我放到避坑章详细说。环境版本选对了后面导入和部署能省一半时间。2.2 环境准备与数据库初始化字符集、驱动和导入顺序先把版本组合确定下来我一般按下面这张表准备环境项推荐配置说明JDK1.8编译级别设为 1.8不要用 JDK17 以上Web 服务器Tomcat 7 或 8Servlet3.x 体系javax.servlet 包数据库MySQL 5.7支持 8.0 需改驱动建库时字符集选 utf8mb4开发工具Eclipse / IDEA / MyEclipse普通 Web 项目导入不强制 Maven数据库驱动mysql-connector-java 5.1.49 或 8.0.33与数据库版本对应数据库初始化是整个项目能否跑起来的第一步顺序错了会引出各种“明明导入成功却没有表”的怪问题。项目压缩包里一般带 SQL 脚本常见命名是 house_rent.sql先打开看开头有没有 create database 语句。如果脚本里已经包含建库语句直接执行整份脚本如果没有就按下面这种手工方式处理。mysql -uroot -p create database house_rent default charset utf8mb4; use house_rent; source D:/download/house_rent/house_rent.sql; show tables;第一行用 root 进入 MySQL 客户端第二行建库并指定 utf8mb4第三行切换当前库第四行 source 执行 SQL 脚本。注意 source 后面要写绝对路径MySQL 不会去“当前项目目录”里找文件这是新手最容易卡住的地方。最后 show tables 检查表清单正常应该看到 member、house_rent、reserve、deposit、contract、payment、news、message、notice、admin_log 这一串表。导入成功后还要检查数据库连接配置。项目的 src 目录下一般有 db.properties 或 jdbc.properties格式类似下面这样drivercom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/house_rent?useUnicodetruecharacterEncodingutf8 usernameroot password123456driver 由你放进 lib 的驱动 jar 决定MySQL5.7 用 com.mysql.jdbc.DriverMySQL8 要换成 com.mysql.cj.jdbc.Driver。url 里的 characterEncodingutf8 必须写在 JDBC URL 上只靠 request.setCharacterEncoding 管不了数据库连接端。username 和 password 改成你本机的实际账号密码别带特殊字符否则 Properties 解析容易出问题。2.3 将项目导入 IDEA 或 Eclipse 并部署到 Tomcat环境准备好之后就是导入和部署。我平时用 IDEA 比较多File - New - Project from Existing Sources选中项目根目录让 IDEA 识别为普通 Web 项目如果用 Eclipse就是 File - Import - Existing Projects into Workspace。无论哪种工具导入后先干三件事把 lib 下的 jar 加进构建路径、验证 web 根目录、修改数据库配置。cd /usr/local/tomcat7/bin ./startup.sh tail -f /usr/local/tomcat7/logs/catalina.out第一行进入 Tomcat 的 bin 目录第二行启动服务第三行实时查看日志。startup.sh 依赖 JAVA_HOME 环境变量没有配置的话脚本会立刻退出Windows 下双击 startup.bat 时窗口一闪而过也是这个原因。Tomcat 启动后访问 http://localhost:8080/项目名/如果看到首页说明部署成功如果页面 404重点检查 IDEA 的 Deployment 配置里 Application context 是否和项目名一致。Tomcat 默认端口是 8080被其他程序占用时可以改 conf/server.xml 里的 Connector port。IDEA 部署时还会出现 1099 端口冲突这是 JMX 端口把它改成 1098 或直接让 IDEA 自动分配即可。2.4 目录结构与两个关键配置文件项目导入后目录一般长这样路径职责src/com.xxx.servletServlet 控制器层src/com.xxx.daoJDBC 数据访问层src/com.xxx.entity实体类对应数据库表src/com.xxx.util数据库连接、JSON、日期工具类WebContent/jsp前台 JSP 页面WebContent/admin后台管理页面WebContent/css、js、images静态资源与轮播图素材WebContent/WEB-INF/web.xmlServlet、过滤器、欢迎页配置database/house_rent.sql数据库脚本web.xml 是动态 Web 项目的中枢本项目的关键配置集中在欢迎页和编码过滤器welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list filter filter-nameencodingFilter/filter-name filter-classcom.xxx.filter.EncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameencodingFilter/filter-name url-pattern/*/url-pattern /filter-mappingwelcome-file-list 决定了用户访问项目根路径时默认展示哪个页面没有这一项访问 / 只会看到目录列表或 404。encodingFilter 的 url-pattern 配成 /* 后所有 JSP 和 Servlet 请求都会经过编码过滤器配合 JSP 头部 pageEncoding 与 JDBC URL 里的 characterEncoding三层编码统一成 UTF-8中文乱码才能彻底压住。3. 功能地图与数据流会员、房源、预定、合同、报表的串联方式3.1 前台与后台两种角色的完整功能边界这套系统的角色划分很清晰前台给普通访客和注册会员看后台是管理员的操作台。前台的功能更像“房源橱窗”会员登录、立即注册、忘记密码通过回答问题找回、首页轮播图、新闻中心、出租信息、求租信息、出售信息、求购信息、信息检索、会员中心、留言板。后台的功能差不多是前台的业务底座新闻资讯管理、发布新闻资讯、注册会员管理、留言板管理、滚动公告管理、发布滚动公告、出租信息管理、发布出租信息、出售信息管理、发布出售信息、求租信息管理、预定信息管理、定金信息管理、合同信息管理、收付款信息、求购信息管理、房屋统计报表、销售租金报表、管理员设置、后台登录日志。功能清单很长但归类后只有三件事内容发布新闻、公告、房源、交易跟进预定、定金、合同、收付款、统计报表房屋统计、销售租金。普通用户在会员中心看到的是自己的资料和订单记录管理员在后台看到的是全量数据两者通过会员主键关联起来。3.2 关键数据表与关系从出租到合同根据这个项目的业务场景核心表大概分成内容表和交易表两类交易表是关键表名核心字段业务含义memberusername、password、question、answer、phone会员账号与密保house_rentpublisher、title、house_type、price、imgs、status出租房源挂牌信息reservehouse_id、member_id、reserve_time、status会员预定记录depositreserve_id、amount、pay_time定金记录contractreserve_id、member_id、start_date、end_date合同信息paymentcontract_id、pay_type、amount收付款流水admin_logadmin_id、login_time、ip后台登录日志从映射关系上看会员对出租房源是一对多一个会员可以预定多套房源每一条预定记录可能对应一笔定金再往后形成合同和收付款。实际操作中reserve 和 deposit 之间建议保持一条预定对应一条定金不要把定金记录直接挂在房源表上否则后面统计“这套房收了多少定金”时会有脏数据。我一般会建议给 status 字段写清楚约定比如 0 表示下架、1 表示上架、2 表示已预定省得翻页面代码猜状态。3.3 业务链从发布房源到租金报表这套系统最值得学习的不是单个 CRUD而是从发布房源到生成报表的完整链路。管理员在后台发布出租信息前台首页和出租信息列表展示房源会员看到合适房源后提交预定管理员在预定信息管理中确认随后进入定金、合同、收付款流程最后房屋统计报表和销售租金报表基于这些业务表做聚合。START TRANSACTION; UPDATE reserve SET status 已付定金 WHERE id 1; INSERT INTO deposit(reserve_id, amount, pay_time) VALUES (1, 500, NOW()); COMMIT;这条 SQL 演示了“收定金”这个事务动作先更新预定状态再插入定金记录两个操作必须同时成功否则会出现定金收了但预定状态还是待处理的情况。MySQL 默认 InnoDB 引擎支持事务START TRANSACTION 开启事务COMMIT 提交中间任何一步失败可以 ROLLBACK 回滚。毕设项目里最容易忽略的就是这种跨表操作的一致性。租金报表的统计逻辑也不复杂核心是按月份分组汇总SELECT DATE_FORMAT(pay_time, %Y-%m) AS pay_month, COUNT(*) AS bill_count, SUM(amount) AS total_amount FROM payment WHERE pay_type 租金 GROUP BY DATE_FORMAT(pay_time, %Y-%m) ORDER BY pay_month DESC;DATE_FORMAT 把完整时间字段 format 成“年-月”字符串COUNT 统计收款笔数SUM 汇总租金总额。GROUP BY 后面要写完整的 DATE_FORMAT 表达式不要直接写别名虽然 MySQL 允许 GROUP BY 别名但换成其他数据库或迁移时容易报错。ORDER BY 用 pay_month DESC 让最新月份排在最前面管理员打开销售租金报表第一眼看到的就是本月数据。3.4 信息检索关键字、价格区间组合与排序前台有信息检索功能检索的本质是组合条件查询。出租信息检索最常见的关键字就是标题、户型、价格区间SQL 写法如下SELECT id, title, house_type, price, create_time FROM house_rent WHERE status 1 AND title LIKE CONCAT(%, ?, %) AND price BETWEEN ? AND ? ORDER BY create_time DESC, id DESC;status 1 保证只查出上架房源下架房源不该出现在前台搜索结果里。LIKE 用 CONCAT 拼接百分号而不是直接把 %关键字% 写进 SQL 模板这是防 SQL 注入的基本功。price BETWEEN ? AND ? 是闭区间查询两个参数分别是最低价和最高价。排序这里用了两列create_time DESC 按时间倒序加 id DESC 是为了同一秒插入多条数据时排序结果仍然稳定。页面端常见做法是搜索框配合 JQuery 的 Ajax 异步提交返回 JSON 后局部刷新列表。这里有个很多人踩过的坑搜索时把整个 JSP 页面刷新一次结果页面跳回首页用户还得重新翻页面。JSP 页面让加载完后刷新一次这个技巧只适合清理缓存或刷新验证码不适合做搜索交互搜索要坚持异步局部刷新。3.5 忘记密码回答密保问题重置密码忘记密码功能在项目里走的是“密保找回”路线注册会员时存密保问题和答案找回时先展示密保问题用户回答正确才能重置密码。逻辑拆开是两步。// 第一步根据用户名查出密保问题展示给用户 String sql1 SELECT question FROM member WHERE username ?; // 第二步用户名和答案同时匹配才允许更新密码 String sql2 UPDATE member SET password ? WHERE username ? AND answer ?;第一步查出的 question 字段用于在页面上显示“你设置的密保问题是你的小学名称是”。第二步更新密码时where 条件必须同时带 username 和 answer不能只按 username 更新。如果只按用户名更新这个接口就会被滥用任何人都可以绕过验证直接改别人密码。答案比对前建议统一 trim()前后端都可能把空格带进去我见过不少“答案明明对但提示错误”的翻车案例问题就出在空格和全角字符上。4. 核心代码拆解LoginServlet、Session 过滤器与 Ajax 房源检索4.1 LoginServlet一次登录请求的完整生命周期登录是前后台共用的入口看懂 LoginServlet 就能摸清这个项目请求处理的套路。核心代码大致如下WebServlet(/login) public class LoginServlet extends HttpServlet { private UserDao userDao new UserDao(); Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username req.getParameter(username); String password req.getParameter(password); User user userDao.findUser(username, password); if (user ! null) { req.getSession().setAttribute(loginUser, user); resp.sendRedirect(req.getContextPath() /index.jsp); } else { req.setAttribute(msg, 用户名或密码错误); req.getRequestDispatcher(/login.jsp).forward(req, resp); } } }这段代码的逻辑顺序是固定的先取参数再查库成功就写 session 并重定向失败就带错误提示转发回登录页。WebServlet(/login) 是 Servlet3.0 的注解式映射等价于在 web.xml 里配 url-pattern项目如果用 web.xml 管理 Servlet映射路径保持一致即可。转发和重定向有本质区别这里值得多说一句。req.getRequestDispatcher(/login.jsp).forward(req, resp) 是一次请求内的跳转request 域里的 msg 属性还能继续用但地址栏不会变resp.sendRedirect(...) 是浏览器重新发起一次请求原来的 request 就丢了好处是刷新页面时不会重复提交表单。登录成功用重定向登录失败用转发这是教科书上也推荐的组合。注意前端表单里 input 的 name 属性必须和 getParameter 的参数名完全一致username 写成 userName 或 user_name后端取到的就是 null登录会一直失败。另外生产环境建议密码做 MD5 存储UserDao 里比对的是加密后的值不要在数据库里存明文密码。4.2 登录拦截过滤器保护后台管理页面后台管理路径不能靠页面隐藏来防过滤器才是正经方案。管理后台的 Servlet 和 JSP 一般集中在 /admin 下拦截器写法如下WebFilter(/admin/*) public class AdminAuthFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; HttpSession session req.getSession(false); User user (session null) ? null : (User) session.getAttribute(loginUser); if (user ! null ADMIN.equals(user.getRole())) { chain.doFilter(req, resp); } else { resp.sendRedirect(req.getContextPath() /login.jsp); } } }WebFilter(/admin/*) 表示拦截所有以 /admin/ 开头的请求包括 JSP 页面和后台 Servlet。逻辑是先取 session 里的 loginUser再判断角色是否是 ADMIN。这里判断不能省普通会员登录成功后 session 里也有 loginUser如果不检查 role普通用户直接访问 /admin/list.jsp 就能进后台这是非常典型的安全漏洞。过滤器的放行逻辑要特别注意。doFilter 方法里登录页 login.jsp、登录接口 loginServlet、验证码 Servlet、静态资源 css/js/images 都不应该被这个过滤器拦截否则用户还没登录就被重定向到登录页页面样式也全丢了。常见做法是把拦截范围缩小到 /admin/*登录相关资源放在 /login 和 /common 下避开过滤器匹配。4.3 JDBC 工具类与预编译 SQL这个项目的数据访问层是手写 JDBC没有 MyBatis 也没有 JPA所以 DBUtil 承担了连接管理职责。核心代码结构如下public class DBUtil { private static Properties props new Properties(); static { try (InputStream in DBUtil.class.getResourceAsStream(/db.properties)) { props.load(in); Class.forName(props.getProperty(driver)); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection( props.getProperty(url), props.getProperty(username), props.getProperty(password) ); } }静态代码块在类加载时执行先读取 db.properties再用 Class.forName 注册数据库驱动这样的好处是连接配置集中在一处换环境只改文件不改代码。getConnection 每次返回新连接注意用完必须关闭否则 MySQL 连接数会被吃光页面就白屏了。DAO 层的查询要坚决用 PreparedStatement我给一个房源检索的示例public ListHouse search(String keyword, double minPrice, double maxPrice) throws SQLException { String sql SELECT id, title, house_type, price, create_time FROM house_rent WHERE status 1 AND title LIKE ? AND price BETWEEN ? AND ?; ListHouse list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, % keyword %); ps.setDouble(2, minPrice); ps.setDouble(3, maxPrice); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { House h new House(); h.setId(rs.getInt(id)); h.setTitle(rs.getString(title)); list.add(h); } } } return list; }参数绑定逻辑第一个参数是关键字LIKE 的百分号拼在 setString 里而不是拼进 SQL 模板第二、三个参数是价格区间的边界值用 setDouble 绑定。这里最关键的是 SQL 模板里只有 ?没有任何用户输入直接拼接PreparedStatement 会把 ? 的值作为参数传给 MySQL而不是解析成可执行代码从根上挡住 SQL 注入。SELECT 字段也尽量列明白不要动不动 SELECT *这个项目是教学向代码更应该在字段层面给后来者做示范。4.4 Ajax JQuery 异步房源检索前台信息检索的交互层用的是 JQuery Ajax后端 Servlet 返回 JSON。后端写法WebServlet(/search) public class SearchServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String keyword req.getParameter(keyword); ListHouse list houseDao.search(keyword, 0, 999999); resp.setContentType(application/json;charsetUTF-8); resp.getWriter().write(new Gson().toJson(list)); } }resp.setContentType 必须在 getWriter 之前调用顺序反了Content-Type 设置不生效前端拿到的虽然是字符串但 MIME 是默认的 text/plainJSON 解析就会失败。Gson 是 Google 的 JSON 库如果项目 lib 里没放 gson 的 jar可以用 fastjson 的 JSON.toJSONString或者手写字符串拼接但手拼要处理中文转义和逗号容易出低级错误有现成库就优先用库。前端页面里用 JQuery 发起请求加载成功后局部刷新房源列表$.ajax({ url: search, type: GET, data: { keyword: $(#keyword).val() }, dataType: json, success: function (data) { var html ; for (var i 0; i data.length; i) { html lia hrefdetail.jsp?id data[i].id data[i].title /a/li; } $(#result).html(html); }, error: function () { alert(搜索失败请检查网络或稍后重试); } });url 写 search 表示相对当前 JSP 路径发送请求要确保它和后端 WebServlet(/search) 的映射一致。data 对象里的 keyword 来自输入框对应后端 req.getParameter(keyword)。dataType 设为 json 后JQuery 会自动把响应字符串解析成数组success 回调里的 data 就能直接用 data[i].title 取属性。前端用字符串拼接渲染列表在数据量小时够用数据量大或字段多了建议改成模板渲染用 document.createElement 逐个构造节点也能避免 XSS 问题。5. 避坑排查404、乱码与 MySQL 连接失败的五个现场5.1 部署与编译期Tomcat 版本冲突、404 与启动闪退第一个典型报错是 UnsupportedClassVersionError。现象Tomcat7 启动时日志里出现 java.lang.UnsupportedClassVersionError提示 class file has wrong version项目根本发布不出去。原因class 文件编译版本高于 JVM 支持上限。JDK8 编译产物是 class version 52.0JDK17 编译产物是 61.0Tomcat7 的 JVM 不认识 61直接拒绝加载。常见来源是 IDE 里 Language level 默认用了 JDK17或者 JAVA_HOME 环境变量指向了新版 JDK。解决检查本机 java -version确认用的是 JDK1.8再在 IDEA 的 Project Structure - Project SDK 和 Modules - Language level 中都改成 8Eclipse 里看 Window - Preferences - Java - Compiler 的 Compiler compliance level。改完 clean project 再重新编译部署不要只改一个地方Project SDK 和 Language level 是两回事容易漏改。第二个是访问项目 404。现象Tomcat 能正常打开首页 http://localhost:8080/但访问项目路径就 404后台目录更是一片空白。原因项目没有真正部署到 Tomcat或者部署的上下文路径和你访问的 URL 对不上。IDEA 里 Run/Debug Configurations - Deployment 中的 Application context 默认可能是 / 或任意字符串但你的浏览器访问的是项目名。解决进入 Tomcat 管理面板或看 webapps 目录确认项目是否被发布IDEA 里把 Application context 改成你要访问的路径比如 /house_rentEclipse 里则是 Server - Add and Remove把项目 Add 到 Tomcat。改完重新启动 Tomcat不要只 redeploy直接 Restart Server 更干净。第三个是 Tomcat 启动闪退。现象./startup.sh 执行后窗口直接消失Windows 下双击 startup.bat 也是闪一下就没localhost:8080 打不开。原因startup.sh 需要 JAVA_HOME 和 CATALINA_HOME 两个环境变量JAVA_HOME 没配置时启动脚本检测失败给出提示后立即退出只是窗口闪太快看不见。解决先在系统环境变量里加入 JAVA_HOME 指向 JDK1.8 安装路径再在 PATH 中加入 %JAVA_HOME%/binCATALINA_HOME 指向 Tomcat 根目录。配置完重新开一个终端再启动。如果 JAVA_HOME 配置没问题但依然闪退用命令行直接执行 startup.bat 能看到真正的错误提示多半是 Tomcat 的 catalina.bat 里 CATALINA_HOME 路径带空格。5.2 运行期中文乱码、MySQL 连接失败与驱动不匹配第四个是页面中文正常但 Ajax 返回的数据乱码。现象JSP 页面显示中文没问题但搜索接口返回的 JSON 在浏览器里是乱码或者注册的中文用户名存进 MySQL 后变成问号。原因编码问题通常同时发生在三层。第一层是 Servlet 输出resp.getWriter 没有指定 UTF-8第二层是 JSP 页面 pageEncoding 不一致第三层是 JDBC URL 缺少 characterEncoding 参数MySQL 里拿到的请求字节流按错误字符集解码。解决Servlet 里在 getWriter 之前先执行 resp.setContentType(application/json;charsetUTF-8)JSP 文件第一行保持 pageEncodingUTF-8db.properties 的 url 末尾加 useUnicodetruecharacterEncodingutf8建库时用 utf8mb4UTF-8 三字节存不了 emoji但 utf8mb4 可以。这样从浏览器到 Servlet 再到 MySQL 的链路全部统一乱码问题才算根治。第五个是 MySQL8 环境连接失败报 SSL 相关错误。现象项目在 MySQL5.7 下跑得好好的换成 MySQL8 后启动报 SQLNonTransientConnectionException详细原因有 SSL connection error或者 Public Key Retrieval is not allowed。原因项目自带驱动是 mysql-connector-java 5.1.xMySQL8 默认认证插件是 caching_sha2_password5.1 驱动不支持这种认证方式同时 MySQL8 默认开启 SSL老驱动解析不了新版握手包。解决把 lib 下的驱动换成 mysql-connector-java 8.0.33db.properties 里的驱动类改成 com.mysql.cj.jdbc.DriverJDBC URL 追加三个参数useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai。useSSLfalse 是关闭 SSL 加密连接allowPublicKeyRetrievaltrue 允许在认证时获取公钥serverTimezone 解决时区偏差导致的时间字段错位。6. 验证技巧30 分钟跑通全链路自测清单项目部署完成、代码能跑起来只是第一步真正判断“这套房子能不能入手”的是业务链路是否通。我拿到任何一版 Java Web 项目都会先按下面的清单走一遍全链路半小时足够走完就知道哪些表、哪些页面、哪些状态值是互相咬合的。验证项操作步骤预期结果前台注册与登录新注册一个会员账号再用该账号登录能进入会员中心错误密码有提示忘记密码用密保问题找回并重置密码新密码能正常登录首页展示查看首页轮播图和出租信息轮播图可切换最新房源出现在列表信息检索按关键字和价格区间搜索房源返回匹配结果无结果时有提示预定流程会员对房源提交预定管理员后台能看到对应预定记录定金与合同后台确认预定并录入定金定金记录生成合同信息能保存统计报表录入多条房后查看报表房屋统计和租金报表数据随操作变化后台日志登录后台退出再登录admin_log 中能看到本次登录时间自测时有个技巧值得养成习惯验证前先把数据库脚本重新导入一遍回到初始数据状态。这样你注册的测试账号、录入了半天的假房源、预定记录都处于干净基线每一条操作的结果都能对应到代码逻辑不会出现“我明明没做这个操作为什么报表里多了条记录”的困惑。排错时不要只盯页面和后台报表去 Tomcat 的 logs 目录翻 catalina.out 和 localhost.logJava Web 项目九个运行时问题有八个都会在日志里留下堆栈。浏览器里按 F12 打开 Network 面板逐个请求检查状态码和响应体404 看路径500 看 Servlet 堆栈200 但页面空白看响应内容是不是 JSON 格式错误。我现在拿到任何一版 Java Web 项目都会强制走一遍这条自测链路再开始改代码。很多“项目不能用”的结论其实都是漏了数据库初始化、驱动版本不对、上下文路径不一致这类环境问题链路先跑通再谈二次开发能省掉大半晚上的无效折腾。希望帮到你。本文还有配套的精品资源点击获取
返回列表