求助:JSP中出现ServletException及ResultSet起始前SQLException异常
问题排查与解决方案
异常原因
你遇到的java.sql.SQLException: Before start of result set异常,核心原因是复用了同一个Statement对象执行两次查询。JDBC规范明确规定:当使用同一个Statement执行新的查询时,之前关联的ResultSet会被自动关闭。你的代码中,在遍历rs1的过程中,用同一个stmt执行了第二次查询,导致rs1提前失效,后续再尝试操作rs1就会触发该异常。
另外原代码还存在几个潜在问题:
- 直接拼接SQL字符串,存在严重的SQL注入风险
- 未正确关闭数据库资源(Connection、Statement、ResultSet),会导致连接泄漏
- HTML结构不严谨:如果查询无结果,
</select></p>会无对应开头标签
修复方案
1. 为每次查询创建独立的Statement/PreparedStatement
不要复用同一个Statement对象,每次查询都使用新的对象,推荐使用PreparedStatement(参数化查询)替代Statement,既解决ResultSet冲突问题,又避免SQL注入。
2. 使用try-with-resources自动管理资源
Java 7及以上支持try-with-resources语法,可自动关闭实现AutoCloseable接口的资源(如Connection、PreparedStatement、ResultSet),无需手动调用close(),避免资源泄漏。
3. 增加空值与无结果判断
避免因username为空或查询无结果导致的逻辑错误与HTML结构问题。
修改后的完整代码
<% // 加载驱动(MySQL 5.x需要,MySQL 8.x可省略,驱动类已改为com.mysql.cj.jdbc.Driver) Class.forName("com.mysql.jdbc.Driver"); // try-with-resources自动关闭资源 try (Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql", "root", "12345"); // 第一个查询:根据用户名获取部门 PreparedStatement deptStmt = con.prepareStatement("select EDepartment from empinfo where EUsername=?")) { String username = (String) session.getAttribute("username"); if (username != null) { deptStmt.setString(1, username); try (ResultSet deptRs = deptStmt.executeQuery()) { if (deptRs.next()) { String department = deptRs.getString("EDepartment"); // 第二个查询:根据部门获取所有用户名,使用独立的PreparedStatement try (PreparedStatement userStmt = con.prepareStatement("select EUsername from empinfo where EDepartment=?")) { userStmt.setString(1, department); try (ResultSet userRs = userStmt.executeQuery()) { %> <select> <% while (userRs.next()) { %> <option><%= userRs.getString("EUsername") %></option> <% } %> </select> <% } } } else { %> <p>未找到当前用户的部门信息</p> <% } } } else { %> <p>请先登录</p> <% } } catch (ClassNotFoundException | SQLException e) { // 实际项目中请使用日志框架记录异常,不要直接打印 e.printStackTrace(); } %>
关键修改点说明
- 拆分两次查询为独立的
PreparedStatement,避免ResultSet被提前关闭 - 使用参数化查询(
?占位符)替代字符串拼接,彻底杜绝SQL注入 - 增加
username非空判断、查询结果存在性判断,处理边界情况 - 用
try-with-resources自动管理数据库资源,避免连接泄漏 - 调整HTML结构,确保只有查询有结果时才输出
<select>标签,避免无效标签
内容的提问来源于stack exchange,提问作者Diana
相关产品推荐
相关产品推荐

