JSP:当通过Ajax POST调用servlet时,RequestDispatcher.forward()不转发

时间:2012-01-04 01:25:18

标签: ajax jsp

我有一个登录表单(login.jsp),其中包含两个输入字段:用户名和密码。

我通过Ajax使用POST来访问登录servlet。

我希望用户登录,如果登录成功,则重定向到另一个名为“search.jsp”的页面。如果不成功,则返回“登录失败”消息,作为要插入“login.jsp”页面中段落的Ajax responseText。

我的一切正常,我的登录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()方法工作,但是当servlet被调用包含Ajax代码的javascript文件时,则不起作用。

1 个答案:

答案 0 :(得分:4)

  

但是不是将请求和响应转发到新的jsp页面'search.jsp',而是将整个search.jsp页面填充回原始的login.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时你的webapp仍然可以工作!)那么你可以检查{{ 1}}标头等于X-Requested-With

XmlHTTPRequest

另见: