我有一个登录表单 (login.jsp),其中包含两个输入字段,用户名和密码。
我正在通过 Ajax 使用 POST 来访问登录 servlet。
我希望用户登录,如果登录成功,则被重定向到另一个名为“search.jsp”的页面。如果不成功,将返回一条“登录失败”消息作为 Ajax 响应文本,插入到“login.jsp”页面的一个段落中。
我的一切正常,我的登录 servlet 通过一个单独的 bean 访问数据库,然后返回该 bean 的一个对象及其准备使用的属性。所以一切都很好。
但是,在用户名和密码通过数据库审核后,我将使用 RequestDispatcher 转发到新的登录页面 (search.jsp)。
这是我的 doPost()
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username,password;
username = request.getParameter("p");
password = request.getParameter("q");
try {
LoginService ls = new LoginService(username,password);
User user = ls.getUserDetails();
if(user.getUsername()!=null && user.getPassword()!=null){
FormService filler = new FormService();
Form fields = filler.getFields();
request.setAttribute("user",user);
request.setAttribute("fields1",fields);
request.setAttribute("fields2",fields);
request.setAttribute("fields3",fields);
HttpSession session = request.getSession(true);
//set attribute for the session
session.setAttribute("user",user.getUsername());
//Now, the RequestDispatcher.forward() is not forwarding to the new page!
//The whole 'search.jsp' page is being stuffed back into the 'login.jsp' page
RequestDispatcher rd = request.getRequestDispatcher("search.jsp");
rd.forward(request,response);
return;
}
else{
PrintWriter out = response.getWriter();
out.println("login failed!");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
但不是将请求和响应转发到新的 jsp 页面“search.jsp”,而是将整个 search.jsp 页面塞回原始的 login.jsp 页面 - 在包含 Ajax responseText 的 html 元素中在登录失败时。
servlet 中的 forward() 方法在从表单操作属性调用 servlet 时起作用,但在 servlet 调用包含 Ajax 代码的 javascript 文件时不起作用。
最佳答案
But instead of forwarding the request and response to the new jsp page 'search.jsp', the whole search.jsp page is being stuffed back into the the original login.jsp page - in the html element which holds the Ajax responseText in when login fails.
这确实是预期的行为。您正在使用 JavaScript 处理请求/响应。您的 JavaScript 代码已将 search.jsp
的响应检索为 responseText
并将其放入 HTML 元素中。
您需要改变这种方法。您需要让响应返回必要的数据,这些数据足以通知 JavaScript,以便它可以正确处理响应。一种常用的数据格式是 JSON。
有点像
response.setContentType("application/json");
if (user != null) {
// ...
response.getWriter().write("{ 'success': true, 'location': 'search.jsp' }");
} else {
response.getWriter().write("{ 'success': false, 'message': 'Unknown login' }");
}
在 JS 中:
var responseJson = eval('(' + xhr.responseText + ')');
if (responseJson.success) {
window.location = responseJson.location;
} else {
document.getElementById('message').innerHTML = responseJson.message;
}
如果你想不引人注目地处理这个问题,以便同一个 servlet 可以在正常(非 ajax)HTTP 请求上重用(这样你的 webapp 在客户端禁用 JS 时仍然可以工作!)那么你可以检查 X-Requested-With
header 等于 XmlHTTPRequest
。
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With")) {
// Handle ajax response (e.g. return JSON data object).
} else {
// Handle normal response (e.g. forward and/or set message as attribute).
}
另见:
关于ajax - JSP:当通过 Ajax POST 调用 servlet 时,RequestDispatcher.forward() 不转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8720961/