本文讲解在jsp中执行数据库查询后,如何避免因循环遍历resultset导致else分支误判的问题,并提供安全、简洁的条件判断写法。
本文讲解在jsp中执行数据库查询后,如何避免因循环遍历resultset导致else分支误判的问题,并提供安全、简洁的条件判断写法。
在上述代码中,开发者意图是:当用户输入的OTP验证通过后,根据会话中保存的邮箱(eemail)查询员工表 empinfo,若该邮箱存在则跳转至修改密码页面;否则提示“Enter Registered Email Id only”。但实际运行时,else 分支始终未输出——根本原因在于 else 被错误地置于 while(rs.next()) 循环内部。
由于 ResultSet rs 是逐行迭代的,只要表中存在至少一条记录,rs.next() 就会返回 true 并进入循环体;而 else 语句会针对每一行不匹配的情况单独执行一次。更严重的是:如果第一行匹配成功(eemail.equals(rs.getString("EEMailID")) 为 true),后续不匹配的行仍会触发 out.println(...),造成逻辑混乱;反之,若首行不匹配但后续有匹配项,该提示又可能被错误输出多次。
✅ 正确做法是:用 rs.next() 判断是否存在匹配记录,而非在循环中逐行比对。因为 SQL 查询已通过 WHERE EEMailID='...' 精确限定,结果集最多只有一条有效记录(邮箱字段应具有唯一性)。因此可直接使用:
Statement stm = con.createStatement();
String m = "SELECT * FROM empinfo WHERE EEMailID = '" + eemail + "'";
ResultSet rs = stm.executeQuery(m);
if (rs.next()) {
String uid = rs.getString("EUsername");
%>
<a href="ChangePassword.jsp?uid=<%=uid%>">Change Password</a>
<p>⚠️ 重要安全提醒:当前代码存在严重的 <strong>SQL 注入漏洞</strong>。拼接字符串构建SQL语句(如 "...'" + eemail + "'")会使攻击者可通过恶意邮箱(例如 ' OR '1'='1)绕过校验、读取或删除全表数据。务必改用预编译语句(PreparedStatement):</p><pre class="brush:php;toolbar:false;">String sql = "SELECT * FROM empinfo WHERE EEMailID = ?";
PreparedStatement pst = con.prepareStatement(sql);
pst.setString(1, eemail);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
String uid = rs.getString("EUsername");
%>
<a href="ChangePassword.jsp?uid=<%=uid%>">Change Password</a>
<p>此外,建议补充资源释放逻辑(关闭 ResultSet、Statement/PreparedStatement 和 Connection),并在生产环境中使用连接池(如 HikariCP)管理数据库连接,提升稳定性与性能。最终,将业务逻辑从 JSP 迁移至 Servlet 或 DAO 层,遵循 MVC 分离原则,才能构建可维护、可测试的企业级应用。</p>










