【问题标题】:JSP: RequestDispatcher.forward() not forwarding when servlet called via Ajax POSTJSP:通过 Ajax POST 调用 servlet 时,RequestDispatcher.forward() 不转发
【发布时间】:2012-02-02 00:08:29
【问题描述】:

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

我通过 Ajax 使用 POST 来访问登录 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 中的 forward() 方法在从表单操作属性调用 servlet 时起作用,但在调用包含 Ajax 代码的 javascript 文件时不起作用。

【问题讨论】:

  • 既然您进行了 AJAX 调用来进行登录,您应该返回 out.println("login success!");当它成功时。收到响应后,使用条件 javascript 更改页面位置或仅显示失败消息。
  • ricz 我不确定你的意思 - 我认为当用户被重定向到新页面时应该暗示成功登录 - 这是我无法开始工作的重定向.
  • AJAX 调用接收响应并将 responseText 放在您告诉它放置的位置。如果你想改变浏览器页面的位置,那么使用javascript来改变它。

标签: ajax jsp


【解决方案1】:

但不是将请求和响应转发到新的 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;
}

如果你想不显眼地处理这个问题,以便在正常(非 ajax)HTTP 请求上可以重用相同的 servlet(这样当客户端禁用 JS 时你的 webapp 仍然可以工作!)那么你可以检查@987654327 @标头等于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).
}

另见:

【讨论】:

    猜你喜欢
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 2013-08-08
    相关资源
    最近更新 更多