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

标签 ajax jsp

我有一个登录表单 (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/

相关文章:

javascript - 将 Ajax 部分 View 模板放在 Assets/javascripts 目录中而不是 Views 目录中,Rails

javascript - 从 HTML 到 ASPX 的 AJAX 调用?

javascript - 如何使闪烁背景变成一种颜色(通知)

java - 如何内嵌显示数据?

html - 将 Now() 插入 MYSQL

javascript - 在ajax调用上加载更多加载gif仅适用于最初存在的div

jquery - 等待 Ajax 函数完成后再开始新的函数

jquery - 如何显示尖括号(包括方括号)之间写入的数据

java - 如何从 servlet 转发到位于单独包中的另一个 servlet?

javascript - 如何通过javascript变量设置JSTL变量值