JSP+JDBC实现登录功能错误提示不显示、URL不跳转问题求助
问题1:输入错误密码无错误提示
原因
你当前在login.jsp里先输出了错误提示的<h2>标签,再通过include引入完整的login.html。而login.html本身是包含完整<html>、<body>标签的独立HTML文档,浏览器解析两个拼接的完整HTML结构时,会忽略掉你提前输出的错误提示内容,最终只渲染login.html的登录表单。
修复方案
将login.html重命名为login.jsp,在表单上方预留错误提示的位置:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login Page</title> </head> <body> <div> <h1>Login Here</h1> <!-- 新增错误提示位置 --> <% if(request.getAttribute("errorMsg") != null) { %> <h2 style="color:red;"><%= request.getAttribute("errorMsg") %></h2> <% } %> <form action="login.jsp" method="post"> <div> <label for="username">Username: </label> <input type="text" name="username" id="username" value="<%= request.getParameter("username")!=null?request.getParameter("username"):"" %>"> </div> <div> <label for="password">Password: </label> <input type="password" name="password" id="password"> </div> <div> <input type="submit" value="Login"> </div> </form> </div> </body> </html>
然后修改login.jsp的错误分支逻辑,不再直接输出错误信息,而是把错误信息存入request域后转发到新的login.jsp:
if (rs.next() == false) { request.setAttribute("errorMsg", "用户名或密码错误!"); RequestDispatcher rd = request.getRequestDispatcher("login.jsp"); rd.forward(request, response); }
问题2:登录成功地址栏显示login.jsp而非welcome.jsp
原因
RequestDispatcher.forward()是服务器内部跳转,整个跳转过程都在服务端完成,浏览器感知不到地址变化,所以地址栏会停留在提交请求的login.jsp地址。
修复方案
登录成功后使用客户端重定向response.sendRedirect()跳转,同时为了避免重定向丢失用户名参数,可以将用户名存入session域:
修改login.jsp的成功分支逻辑:
else { // 将用户名存入session,供welcome.jsp取值 session.setAttribute("loginUser", username); // 客户端重定向,地址栏会变成welcome.jsp response.sendRedirect("welcome.jsp"); }
对应修改welcome.jsp的取值逻辑,从session中取用户名,同时增加未登录校验:
<%@page import="java.util.*, java.io.*, java.sql.*, javax.sql.*, java.time.format.DateTimeFormatter, java.time.LocalDateTime"%> <html> <body> <% String username = (String) session.getAttribute("loginUser"); // 未登录访问直接跳回登录页 if(username == null) { response.sendRedirect("login.jsp"); return; } out.println("<h2>Logged in successfully</h2>"); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); LocalDateTime now = LocalDateTime.now(); out.println("<h3>Welcome " + username +"</h3>"); out.println(dtf.format(now)); %> </body> </html>
额外安全优化
你当前使用Statement拼接SQL字符串存在严重的SQL注入风险,攻击者可以通过输入特殊用户名直接绕过登录校验,建议替换为PreparedStatement:
// 替换原有Statement相关代码 String sql = "select * from myusers where username = ? and password = ?"; PreparedStatement pst = conn.prepareStatement(sql); pst.setString(1, username); pst.setString(2, password); ResultSet rs = pst.executeQuery();
同时建议添加finally块关闭数据库连接,避免异常时连接泄露。
内容的提问来源于stack exchange,提问作者P Sai Akhil
相关产品推荐
相关产品推荐

