JSP:当通过Ajax POST调用Servlet时,RequestDispatcher.forward()无法转发。

3
我有一个登录表单(login.jsp),有两个输入项,分别是用户名和密码。
我使用POST通过Ajax访问登录servlet。
我希望用户登录成功后能够重定向到另一个名为'search.jsp'的页面。如果登录失败,则作为Ajax responseText返回“登录失败”消息,并插入到“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时,servlet中的forward()方法有效,但在包含Ajax代码的javascript文件中调用servlet时无效。

由于您正在进行AJAX调用以进行登录,因此当成功时应返回out.println(“登录成功!”)。 在接收到响应后,使用条件JavaScript更改页面的位置或仅显示失败消息。 - rickz
我不确定你的意思 - 我认为成功登录应该隐含在用户被重定向到新页面时 - 我无法让这个重定向工作。 - berzerk
AJAX调用接收响应并将responseText放置在您指定的位置。如果您想更改浏览器页面的位置,则使用JavaScript进行更改。 - rickz
请访问 http://www.roseindia.net/javascript/javascript-location-replace.shtml 了解相关的编程内容。 - rickz
或者访问http://www.ezineasp.net/Samples/Javascript/Location-Object/Location-Href/Default.aspx。 - rickz
显示剩余2条评论
1个回答

4
相反,整个search.jsp页面被塞回原始的login.jsp页面,而不是将请求和响应转发到新的jsp页面“search.jsp”,这发生在当登录失败时html元素中保存Ajax responseText时。
这确实是预期行为。您正在使用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请求中重复使用(这样当客户端禁用JS时您的web应用程序仍然可以正常工作!),那么您可以检查 X-Requested-With 标头是否等于 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).
}

参见:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接