简介这套基于WebGIS的淮河水量水质监测系统将地理信息系统与互联网技术相结合覆盖水量水质实时监测、数据分析与辅助决策等核心功能。项目Java源码与说明文档齐全适合计算机相关专业学生用于毕业设计、课程设计或项目实训也适合初学入门者学习前后端与GIS整合思路。压缩包共1092个文件大小约39.98MB主要包含Java源码及编译后的class文件、JSP页面、JavaScript与CSS前端资源、PNG图片、JAR依赖库及XML配置等目录结构完整便于按模块查阅和二次开发。目前已有178人学习下载代码经过验证可稳定运行并附有项目说明能帮助读者快速理解监测站点数据采集、水质评估和趋势预测的落地实现。若在此基础上继续扩展还可用于水环境管理相关课题的进一步研究。1. 一个能直接跑起来的 WebGIS 淮河水量水质监测系统它到底解决了什么如果你正在做水环境方向的毕业设计或课程设计导师大概率会提一句“最好带个地图展示”然后你就得在前后端分离、三维可视化、微服务这些词里纠结半天。这份基于 WebGIS 的淮河水量水质监测系统源码包走的是另一条路——经典的 JSP Servlet JDBC 三层架构加 GIS 地图页面解压配置好数据库就能运行。它解决的正是这类项目最头疼的几件事监测站点怎么在地图上展示、水量和水质数据怎么入库、新增一条监测记录后前端如何立刻刷新。适合计科、大数据、物联网、信息安全方向的学生拿来当毕设底子也适合老师做课堂演示或者刚接触 Java Web 的人作为第一个能完整跑通的项目。2. WebGIS 监测系统的三层架构为什么这套源码选 JSP Servlet 而不是前后端分离2.1 WebGIS 的本质地图只是容器业务数据才是主角很多人在拿到这个项目时会误以为 WebGIS 很难其实把“WebGIS”拆开看它就是“在网页上展示地理信息”。项目里的地图组件负责显示底图和站点标记真正的核心业务——水位记录、水质指标、站点管理——全部存在关系型数据库里通过 Java 代码读写。这套源码没有用 GeoServer、PostGIS 这类重型 GIS 服务而是直接在页面上加载瓦片底图再用 JavaScript 把监测站点画上去。这种做法的好处非常明显部署简单一台 Tomcat 加一个 MySQL 就够不需要额外安装 GIS 服务器。我拆过不少类似的项目这种“轻 GIS”方案在课程设计和毕业设计里是最稳的选择。你不需要懂地图投影、空间索引这些概念只需要会写 SQL 和 JavaScript 就能把功能做出来而且答辩时能讲清楚每一条数据从哪来到哪去。对于评审老师来说他们更关心你有没有把“数据采集→存储→展示”这条链路跑通而不是你用了多炫酷的地图引擎。2.2 从源码里的类名反推项目结构拿到源码包解压后你会在 src 目录下看到几个关键的 Java 类它们基本就是整个项目的地图类名所属层职责推测AddWaterQualityServlet控制层接收前端提交的水质数据调用业务层写入数据库WaterQualityStationDaoImpl数据访问层实现对水质监测站点的增删改查WaterLevelDaoImpl数据访问层实现对水位数据的查询和统计DaoImpl结尾的类名说明项目采用了 DAO 模式即“接口 实现类”分离。以WaterQualityStationDaoImpl为例它大概率实现了某个WaterQualityStationDao接口接口里定义了addStation()、deleteStation()、findAllStations()这类方法而其实现类里写的是 JDBC 操作数据库的具体代码。如果你打开一个DaoImpl文件看到的应该是类似下面的结构public class WaterQualityStationDaoImpl implements WaterQualityStationDao { // 数据库连接工具类通常由 JDBCUtil 统一管理 private JDBCUtil jdbcUtil new JDBCUtil(); Override public int addStation(WaterQualityStation station) { String sql INSERT INTO t_station(station_name, longitude, latitude, station_type) VALUES(?, ?, ?, ?); // 预编译 SQL防止拼接注入 PreparedStatement ps jdbcUtil.getConnection().prepareStatement(sql); ps.setString(1, station.getStationName()); ps.setDouble(2, station.getLongitude()); ps.setDouble(3, station.getLatitude()); ps.setString(4, station.getStationType()); return ps.executeUpdate(); } }这段代码的逻辑很直观先拿到数据库连接然后构造INSERT语句用PreparedStatement的setString、setDouble方法按顺序填充字段值最后执行更新并返回受影响行数。这里要注意setDouble和setString的顺序必须和 SQL 语句里的?占位符一一对应否则数据会写错列。很多同学在二次开发时新增字段只改了 SQL 没改set语句结果运行时报“列索引超出范围”就是占位符数量对不上。2.3 Servlet 层是怎么把请求转给 DAO 的AddWaterQualityServlet是入口前端表单提交的数据最终会落到这里。Servlet 的生命周期很简单doPost()方法接收请求解析参数封装成实体对象调用 DAO 写入数据库。关键代码逻辑大致如下protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); // 从前端表单获取监测数据 String stationId request.getParameter(stationId); String phValue request.getParameter(phValue); String turbidity request.getParameter(turbidity); String recordTime request.getParameter(recordTime); // 封装成实体对象 WaterQualityRecord record new WaterQualityRecord(); record.setStationId(Integer.parseInt(stationId)); record.setPhValue(Double.parseDouble(phValue)); record.setTurbidity(Double.parseDouble(turbidity)); record.setRecordTime(Timestamp.valueOf(recordTime)); // 调用 DAO 层保存 WaterQualityDao dao new WaterQualityDaoImpl(); boolean isSuccess dao.addRecord(record); // 根据结果跳转或刷新页面 if (isSuccess) { response.sendRedirect(stationDetail.jsp?stationId stationId); } else { request.setAttribute(errorMsg, 水质数据保存失败); request.getRequestDispatcher(addWaterQuality.jsp).forward(request, response); } }这里有个细节值得注意Timestamp.valueOf(recordTime)对日期字符串的格式要求非常严格必须是yyyy-MM-dd HH:mm:ss少了空格或者用了其他分隔符直接抛异常。我一般建议前端用input typedatetime-local控件JavaScript 处理成这种标准格式再提交能省掉很多麻烦。另外sendRedirect和forward的区别也要清楚前者是浏览器重新发起请求地址栏会变后者是服务器内部转发地址栏不变。在这个场景下新增成功后跳转到详情页用重定向合适因为刷新页面不会重复提交表单。3. 部署与运行环境配置、数据库初始化和工程导入全流程3.1 环境版本怎么搭配才不会翻车这是整个部署过程中最容易踩坑的地方。项目是基于 JSP Servlet 的老三层架构对运行环境有明确的兼容性要求。按照我多次部署这类项目的经验推荐的组合是JDK 1.8Tomcat 8.5 或 9.0MySQL 5.7IDE 用 Eclipse 或 IntelliJ IDEA 都行。为什么不建议用 JDK 11 或更高版本因为 Tomcat 8.5 在 JDK 11 上跑老的 Web 项目时有些反射相关的操作会收到IllegalAccessError警告虽然多数情况下不影响运行但在答辩演示时突然报一个异常心里总不踏实。MySQL 5.7 和 8.0 的驱动也有区别。5.7 用com.mysql.jdbc.Driver8.0 必须换成com.mysql.cj.jdbc.Driver同时连接 URL 还得加上serverTimezoneAsia/Shanghai参数否则会报时区错误。如果你下载的源码包里lib目录下的 mysql-connector 是旧版5.x.jar那就老老实实用 MySQL 5.7不要为了追求“新版”去装 MySQL 8.0 然后发现连接不上白白浪费时间。3.2 数据库初始化建库、建表、导入数据一般在源码包的解压目录下都会有一个sql或db文件夹里面放着初始化脚本。如果没找到就需要自己手动建表。建表语句要覆盖三个核心业务表监测站点表、水质记录表、水位记录表。下面是常见结构的实例-- 1. 创建数据库 CREATE DATABASE IF NOT EXISTS huaihe_webgis DEFAULT CHARACTER SET utf8mb4; USE huaihe_webgis; -- 2. 监测站点表 CREATE TABLE t_station ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, station_name VARCHAR(50) NOT NULL COMMENT 站点名称, longitude DECIMAL(10, 6) NOT NULL COMMENT 经度, latitude DECIMAL(10, 6) NOT NULL COMMENT 纬度, station_type VARCHAR(20) DEFAULT 水质站 COMMENT 站点类型水量站/水质站, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB COMMENT淮河监测站点表; -- 3. 水质记录表 CREATE TABLE t_water_quality ( id INT PRIMARY KEY AUTO_INCREMENT, station_id INT NOT NULL COMMENT 关联的站点ID, ph_value DECIMAL(4, 2) COMMENT PH值, turbidity DECIMAL(8, 2) COMMENT 浊度(NTU), dissolved_oxygen DECIMAL(5, 2) COMMENT 溶解氧(mg/L), ammonia_nitrogen DECIMAL(6, 2) COMMENT 氨氮(mg/L), record_time DATETIME NOT NULL COMMENT 采样时间, FOREIGN KEY (station_id) REFERENCES t_station(id) ) ENGINEInnoDB COMMENT水质监测记录表; -- 4. 水位记录表 CREATE TABLE t_water_level ( id INT PRIMARY KEY AUTO_INCREMENT, station_id INT NOT NULL, water_level DECIMAL(8, 3) COMMENT 水位(米), flow_rate DECIMAL(10, 3) COMMENT 流量(m³/s), record_time DATETIME NOT NULL, FOREIGN KEY (station_id) REFERENCES t_station(id) ) ENGINEInnoDB COMMENT水量水位记录表; -- 5. 写几条测试数据确保页面打开有内容 INSERT INTO t_station(station_name, longitude, latitude, station_type) VALUES (王家坝水文站, 115.5742, 32.4231, 水量站), (蚌埠闸水质站, 117.3604, 32.9167, 水质站), (淮南田家庵监测站, 117.0183, 32.6421, 水质站);在水质记录表和水量记录表里都加了外键约束目的是保证每一条监测数据都能对应到具体的站点。但在实际开发中我建议外键约束只在开发环境保留生产环境或答辩演示前可以去掉因为外键会影响大数据量下的插入性能而且如果有人在页面上删了站点外键会阻止删除报一个很突兀的 SQL 异常。站点表里的longitude和latitude用了DECIMAL(10,6)保留 6 位小数这对应了 GPS 坐标的精度需求注意别用FLOAT——浮点数在经纬度计算时会产生微小误差虽然平时看不出来但在 GIS 叠加图层时会有一点偏移。3.3 把工程导入 IDEA 并配置 Tomcat打开 IntelliJ IDEA选择File → New → Project from Existing Sources定位到解压后的项目目录。如果你的源码包里有.iml文件或.idea目录直接选“Import project from external model → Eclipse”也可以。导入完成后要确认三件事第一检查Project Structure → Libraries里有没有lib目录下的所有 jar 包包括mysql-connector-java、jstl.jar、standard.jar一个都不能少。缺了这些项目编译能过但启动时访问页面会直接抛ClassNotFoundException。第二File → Settings → Build, Execution, Deployment → Application Servers里添加本机的 Tomcat 路径然后把项目部署到 Tomcat 的Deployment选项卡中Application context 填/huaihe。注意根路径一定要和前端页面里的请求路径保持一致比如前端fetch(huaihe/AddWaterQualityServlet)你的 context 就得是huaihe否则 404。第三如果项目里有.properties配置文件检查数据库连接的 URL、用户名、密码是否和本地环境一致jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/huaihe_webgis?useUnicodetruecharacterEncodingUTF-8 jdbc.usernameroot jdbc.password123456characterEncodingUTF-8这个参数最容易被漏。漏掉之后中文站名在页面上显示成???数据库里存的也是乱码。还有一个常见坑是密码里有特殊字符比如或#直接写在 properties 里会被截断或者转义报错。如果密码确实有特殊字符建议在 JDBCUtil 里用Properties.load()读取后用字符串拼接或者用setProperty手动重写。3.4 启动 Tomcat 并完成三连验证配置好之后启动 Tomcat在浏览器访问http://localhost:8080/huaihe/应该能看到系统主页面。验证三板斧第一步看地图页面。正常情况是底图加载出来上面有几个标记点对应你刚插入的测试站点数据。如果地图空白八成是 JavaScript 报错按 F12 打开控制台看有没有 404 或跨域警告。第二步加一条数据。进入水质数据录入页面填一个 PH 值和浊度提交后跳转到站点详情页看看新增的数据有没有出现在列表里。这时候去 MySQL 里执行SELECT * FROM t_water_quality ORDER BY id DESC LIMIT 5;能看到刚才提交的记录说明 Servlet 到 DAO 到数据库这条链路是通的。第三步检查页面交互。点击地图上的站点标记此时应该弹出一个信息窗口或者跳转到对应站点的详情页面。如果点击没反应看浏览器控制台报什么错——最常见的是Uncaught ReferenceError: xxx is not defined说明 JSP 里的 JavaScript 函数定义和调用的地方作用域不一致。4. 二次开发实战从 DAO 层到页面把功能改成自己的业务4.1 给 DAO 层加一个“按月份查平均水质”的方法拿到源码之后几乎所有人都会想改点东西让它更像自己的项目。最安全的改法是从 DAO 层开始因为这里不涉及页面逻辑改错了不影响其他地方。假设我们要加一个“查询某站点最近三个月平均水质”的功能先在WaterQualityDao接口里加方法声明然后在实现类里写 SQLpublic interface WaterQualityDao { // 原有方法 int addRecord(WaterQualityRecord record); // 新增按站点ID和月份获取水质平均值 MapString, Double getAverageQuality(int stationId, String startMonth, String endMonth); }实现类里的代码Override public MapString, Double getAverageQuality(int stationId, String startMonth, String endMonth) { String sql SELECT AVG(ph_value) AS avg_ph, AVG(turbidity) AS avg_turbidity, AVG(ammonia_nitrogen) AS avg_ammonia FROM t_water_quality WHERE station_id ? AND DATE_FORMAT(record_time, %Y-%m) BETWEEN ? AND ?; MapString, Double result new HashMap(); try (PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, stationId); ps.setString(2, startMonth); ps.setString(3, endMonth); ResultSet rs ps.executeQuery(); if (rs.next()) { result.put(avg_ph, rs.getDouble(avg_ph)); result.put(avg_turbidity, rs.getDouble(avg_turbidity)); result.put(avg_ammonia, rs.getDouble(avg_ammonia)); } } catch (SQLException e) { e.printStackTrace(); } return result; }注意DATE_FORMAT(record_time, %Y-%m)这一步它把时间字段格式化成2024-01这种形式配合BETWEEN就能筛选出指定月份区间内的数据。这里有个边界坑startMonth和endMonth的格式必须是yyyy-MM如果你传了2024-1少个零SQL 里会比较失败返回空结果。所以在前端传参时就要统一格式化或者在 Servlet 层做一次规范化处理。4.2 在 Servlet 层新增一个统计接口并挂到 web.xml有了 DAO 方法下一步是写一个 Servlet 来接收前端请求、调用 DAO、返回 JSON。用 Gson 库可以省不少事WebServlet(/averageQualityServlet) public class AverageQualityServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int stationId Integer.parseInt(request.getParameter(stationId)); String startMonth request.getParameter(startMonth); String endMonth request.getParameter(endMonth); WaterQualityDao dao new WaterQualityDaoImpl(); MapString, Double avg dao.getAverageQuality(stationId, startMonth, endMonth); response.setContentType(application/json;charsetUTF-8); response.getWriter().write(new Gson().toJson(avg)); } }如果你的项目用的是老式web.xml配置而不是注解那就需要在web.xml里手动加一段servlet servlet-nameaverageQualityServlet/servlet-name servlet-classcom.yourpackage.servlet.AverageQualityServlet/servlet-class /servlet servlet-mapping servlet-nameaverageQualityServlet/servlet-name url-pattern/averageQualityServlet/url-pattern /servlet-mapping这个接口用 GET 请求就能访问传参形式如http://localhost:8080/huaihe/averageQualityServlet?stationId1startMonth2024-01endMonth2024-03返回的 JSON 类似{avg_ph:7.32,avg_turbidity:18.6,avg_ammonia:0.42}。有一个细节如果三月份查询结果为空返回的 JSON 会是{}而不是{avg_ph:0}前端处理时要判断Map是否为空否则会显示NaN或undefined。4.3 把统计结果画到地图上标记点按水质等级变色数据接口有了现在要做的是让页面上的站点标记根据水质等级显示不同颜色。这里我以 Leaflet 为例因为它是纯前端库不需要后端额外配置。在 JSP 页面里的 JavaScript 代码中操作大致是// 假设 map 已初始化stations 是后台输出的站点JSON数组 stations.forEach(function(station) { var color #3388ff; // 默认蓝色 // 调用统计接口获取该站点平均值 fetch(averageQualityServlet?stationId station.id startMonth2024-01endMonth2024-03) .then(function(resp) { return resp.json(); }) .then(function(data) { if (data.avg_ph) { // 简单分级PH 6.5 偏酸 8.5 偏碱中间正常 if (data.avg_ph 6.5) color #e74c3c; else if (data.avg_ph 8.5) color #f39c12; else color #2ecc71; } // 用带颜色的小圆点标记站点 L.circleMarker([station.latitude, station.longitude], { radius: 8, color: color, fillColor: color, fillOpacity: 0.8 }).addTo(map).bindPopup(station.stationName br平均PH: (data.avg_ph || 暂无数据)); }); });这里的fetch是 ES6 的 Ajax 写法页面按顺序请求每个站点的平均数据再动态改变标记点颜色。需要注意如果站点数量多这种逐个请求的方案会有点慢常见做法是后端提供一个一次性返回所有站点平均值的接口或者在前端用Promise.all并行请求。对于毕设演示来说站点数量一般不超过二十个逐个请求完全够用不必为了性能过度设计。颜色分级的边界值也是可以改的。上面写的 PH 小于 6.5 是偏酸大于 8.5 是偏碱这个阈值依据的是《地表水环境质量标准》的基本项如果你想按溶解氧或氨氮分级把判断条件换成对应的字段就行。改的时候记得把bindPopup里的avg_ph也对应改掉否则弹窗显示的数据和颜色代表的指标不一致答辩时被问到会非常尴尬。5. 避坑与排查部署期最常见的五个问题记录5.1 访问页面 404Tomcat 控制台却没有任何报错现象启动 Tomcat 正常浏览器访问http://localhost:8080/huaihe/返回 404但 Tomcat 日志里干净的像什么都没发生过。原因项目的 Deployment context 配置不对。很多人导入项目后IDEA 自动生成的 Application context 是/或者带有原工程文件名的路径比如/webgis_huaihe_water,前端页面里引用的资源路径就全对不上了。解决打开 IDEA 的Run/Debug Configurations找到 Tomcat Server 配置在Deployment标签页把Application context改成/huaihe和前端代码里所有请求路径的根保持一致。改完重启 Tomcat。另外项目解压后的路径有中文也会导致这种问题源码包的说明里明确写过“项目名字和项目路径不要用中文”Tomcat 对非 ASCII 字符的路径解析本身就是个玄学直接规避是最稳的。5.2 页面打不开报ClassNotFoundException: com.mysql.jdbc.Driver现象部署后访问首页页面直接弹 500 错误控制台显示找不到 JDBC 驱动类。原因lib 目录下的 jar 没有正确引入到项目的 Build Path。IDEA 有时候只会把 lib 目录识别为普通文件夹不会自动把里面的 jar 加入依赖。解决File → Project Structure → Libraries → → Java手动选中lib目录确认加载进来。同时检查Artifacts里打包输出的 lib 是否包含 jar——右键Artifacts → Available Elements把 lib 下的 jar 拖到WEB-INF/lib下。这一步漏掉的话编译不报错运行时依然找不到类。5.3 地图底图加载不出来其他页面功能正常现象页面框架出来了图表、表格都有了就地图那块是灰的或者空白浏览器控制台提示某地图瓦片地址返回 403。原因这是最常见的跨域或 HTTPS 混合内容问题。项目里地图瓦片的地址如果是http://开头而你的站点是通过https://访问的浏览器会拦截“不安全”的 HTTP 请求导致瓦片加载失败。另外有些地图服务商要求请求必须带密钥token如果源码里没有配自然加载不出来。解决先确认浏览器控制台的报错类型。如果是Mixed Content把当前项目在 IDEA 里配置成 HTTP 访问即可。如果是 403检查 JSP 里加载地图的script代码里有没有key或token参数。实在排查不清楚可以临时把底图换成公开的 OpenStreetMap 瓦片在加载地图的 JavaScript 代码中把tileLayer的 URL 改成https://tile.openstreetmap.org/{z}/{x}/{y}.png这段代码调试完再换回项目原始配置。5.4 中文数据写入数据库后显示乱码问号或者 现象通过页面往数据库里插入站点名称“王家坝水文站”查询后发现是???。原因链路里有三层编码不一致。第一数据库连接 URL 少了characterEncodingUTF-8参数第二MySQL 表本身的字符集不是 utf8mb4第三JSP 页面没有写% page contentTypetext/html;charsetUTF-8 %。解决按链条排查。先看数据库连接 URL——大多数情况下是这里的问题加上useUnicodetruecharacterEncodingUTF-8后重启 Tomcat。如果还不行检查建表语句是否指定了DEFAULT CHARACTER SET utf8mb4。最后确认 JSP 文件头部有charsetUTF-8的声明。一个省事的办法是在 Tomcat 的server.xml的Connector节点里加URIEncodingUTF-8这样 GET 请求的中文参数也能正确解码。5.5 新增数据按钮点了没反应F12 看到 500 状态码现象点击“新增监测数据”按钮页面没有跳转也没有任何提示F12 网络面板显示请求的 Servlet 返回 500。原因服务器端代码抛了异常但页面没有做异常捕获和友好提示导致用户无感知。最常见的原因前端传的某个字段为空Double.parseDouble拿到空字符串抛NumberFormatException。解决在 Servlet 的doPost方法里加参数校验捕获异常并回传提示信息。比如把Double.parseDouble(request.getParameter(phValue))包一层判断double phValue 0; if (request.getParameter(phValue) ! null !request.getParameter(phValue).isEmpty()) { phValue Double.parseDouble(request.getParameter(phValue)); } else { request.setAttribute(errorMsg, PH值不能为空); request.getRequestDispatcher(addWaterQuality.jsp).forward(request, response); return; }“不能为空”判断一定要做在前端但现实情况是前端校验经常被绕过所以后端这层校验是底线。养成这个习惯之后你会省去大量排查“用户填了非法数据导致 500”的时间。在验证阶段还有一个通用套路故意在页面提交一个非法值比如 PH 填 “abc”看系统是否引用了刚才的校验代码如果仍然 500说明 Servlet 里还有没覆盖到的字段逐个补上就干净了。6. 验证系统真正可用的实操技巧从页面到库再到地图的链路巡检拿到源码并且能跑起来这只是第一步。你敢不敢在答辩现场当着老师的面从头到尾操作一遍我通常在交付这类项目前会做一套“链路巡检”动作大概花二十分钟能发现九成以上的隐患。第一趟从页面加到数据库。在监测数据录入页随便填一组数据提交后打开终端查询刚刚插入的记录确认字段值完全一致。这一步查的是 Servlet 参数解析和 DAO 写入是否正确最容易被忽略的是时间字段——很多前端控件回传的时间格式是2024-06-01T10:30带 TTimestamp.valueOf直接报错需要在 Servlet 里把T替换成空格。第二趟从数据库到页面。手动把一条数据的 PH 值改成明显偏大的数比如9.8刷新详情页看看地图上的站点颜色有没有变成警示色。这一步验证的是查询逻辑和前端渲染逻辑是否协同工作尤其是 JavaScript 里有没有对异常值做过滤。如果颜色没变多半是 JSP 里取数据用了一个已经废弃的字段名和数据库列对不上。第三趟用压测确认接口没被写死。打开 JMeter 或者直接写一个简单的 Java 多线程循环调用averageQualityServlet线程数开到 50循环 100 次看有没有超时或报错。老式的 JDBC 直连在没有连接池的情况下50 个并发就会暴露出连接未关闭的问题——Connection用完不close()连接数耗尽后 Tomcat 直接拒绝服务。如果你的项目里有这个问题正好趁答辩前修掉try (Connection conn jdbcUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { // 业务操作 } catch (SQLException e) { e.printStackTrace(); }用try-with-resources语法确保连接自动关闭改动量不大但对项目评价的提升是实打实的。这套巡检流程走完之后我还会顺手做一件事把测试时插入的垃圾数据清掉重新导入一份干净的初始化数据。因为答辩时老师可能会打开数据库查看如果里面是一堆test1、test2这种测试记录观感非常差。从最早调试这个淮河项目开始我就养成了一个习惯每次部署完这类 WebGIS 老项目数据库初始化检查清单必须从头到尾走一遍——驱动版本、URL 编码、表字符集、外键约束、测试数据五样缺一不可。因为绝大多数翻车事故都是这几处组合出来的提前排查一遍比现场救火体面得多。希望这份梳理能帮你在部署和二次开发时少走几步弯路。本文还有配套的精品资源点击获取
