validation.java
try
{
conn = dsEvent.getConnection();
String userCheck = "select * from customer";
stmt = conn.createStatement();
rs = stmt.executeQuery(userCheck);
while(rs.next()){
if((email.equals(rs.getString("email")))&&(password.equals(rs.getString("password"))))
{
RequestDispatcher rd = req.getRequestDispatcher("/success.jsp");
rd.forward(req,res);
}
else
{
req.getSession().setAttribute("error", "The email or password you entered is incorrect. Please try again");
res.sendRedirect(this.getServletContext().getContextPath() + "/index.jsp");
}
}
} catch (SQLException ex) {
System.err.println(ex);
}
}
索引.jsp
<body>
<h2>System</h2>
<p style ="color:red"><%=session.getAttribute("error")!=null ? "":session.getAttribute("error") %></p>
<form method ="post" action="validation">
Please Login: <br/>
Email: <input type="email" name="email" required/><br/>
Password: <input type="password" name="password" required/><br/>
<input type ="submit" value="Login"/>
</form>
</body>
我正在验证电子邮件和密码。因此,当用户输入正确的电子邮件和密码时,它将转发到成功.jsp。如果用户输入错误的详细信息,它将重定向页面以索引.jsp以及错误。
但我似乎无法让它在错误的细节部分工作。它给了我
警告: StandardWrapperValve[com.events.ValidationServlet]: PWC1406: Servlet.service() for servlet com.events.ValidationServlet threw 例外
似乎ResultSet
至少包含两行,因此服务器至少两次执行转发和/或重定向或两者的组合,这是不允许的,因为您尝试在响应已经关闭时编写响应。
解决方案:将验证代码移到任何循环之外。确保对 RequestDispatcher#forward
或 HttpServletResponse#redirect
的调用仅在 servlet 中的方法中发生一次。
此外,我不建议在这种情况下使用重定向,因为它会生成一个新的请求/响应周期,因此存储在请求中的所有属性都不会传递给这个新的请求/响应。
这主要是对路易吉·门多萨答案的补充。不能在循环中forward
或sendRedirect
,除非在循环中只传递一次。就像你一样,servlet 会抛出一个导致你的错误的异常。
您可以将这些代码移到循环之外:
boolean found = false;
while( (! found) && rs.next()){
if((email.equals(rs.getString("email")))&&(password.equals(rs.getString("password"))))
{
found = true;
}
}
if (found) {
RequestDispatcher rd = req.getRequestDispatcher("/success.jsp");
rd.forward(req,res);
}
else
{
req.getSession().setAttribute("error", "The email or password you entered is incorrect. Please try again");
res.sendRedirect(this.getServletContext().getContextPath() + "/index.jsp");
}
但是在这里你是在结果集上手动循环,当你可以让数据库找到是否有匹配项时:
conn = dsEvent.getConnection();
String userCheck = "select count(*) from customer where email = ? and password = ?";
stmt = conn.prepareStatement();
stmt.setString(1, email);
stmt.setString(2, password);
rs = stmt.executeQuery(userCheck);
if (rs.next().getInt(1) > 0)
RequestDispatcher rd = req.getRequestDispatcher("/success.jsp");
rd.forward(req,res);
}
else
{
req.getSession().setAttribute("error", "The email or password you entered is incorrect. Please try again");
res.sendRedirect(this.getServletContext().getContextPath() + "/index.jsp");
}
遍历整个resultset
并验证用户是否存在,而是尝试更改select
查询以检查数据库中是否存在特定用户。
为此,请尝试以下代码
String email = request.getParameter("email");
String password = request.getParameter("password");
String userCheck = "select * from tableName where username = ? AND password = ?";
PreparedStatement ps = con.prepareStatement(userCheck);
ps.setString(1, email);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
而不仅仅是检查resultset
是否为空。
要检查结果集是否为空,请输入以下代码:
if(rs.isBeforeFirst()) {
request.getSession().setAttribute("email",email);
response.sendRedirect("success.jsp");
} else {
request.setAttribute("error", "Invalid Username & Password");
request.getRequestDispatcher("index.jsp").forward(request, response);
}
有关isBeforeFirst()
方法,请查看此处。
同时更改index.jsp
以显示错误消息
<p style ="color:red"><%=request.getAttribute("error")!=null ? request.getAttribute("error"): "" %></p>