JSP:调用RequestDispatcher.forward()不转发时,通过Ajax POST所谓的servlet [英] JSP: RequestDispatcher.forward() not forwarding when servlet called via Ajax POST

查看:260
本文介绍了JSP:调用RequestDispatcher.forward()不转发时,通过Ajax POST所谓的servlet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个登录表单(login.jsp的)有两个输入域,用户名和密码。

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

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

我拥有的一切工作,我登录的servlet通过一个单独的bean访问数据库,那么这个Bean的对象是与它的属性就可以使用返回。因此,所有好到那里。

不过,用户名和密码不屑一顾,数据库之后,然后我使用了RequestDispatcher的转发到新的登陆页面(search.jsp的)。

下面是我的doPost()

 保护无效的doPost(HttpServletRequest的请求,HttpServletResponse的响应)抛出了ServletException,IOException异常{
    字符串的用户名,密码;
    的用户名的request.getParameter =(P);
    密码=的request.getParameter(Q);

    尝试 {
        login服务LS =新的login服务(用户名,密码);
        用户USER = ls.getUserDetails();

        如果(user.getUsername()= NULL和放大器;!&安培;!user.getPassword()= NULL){
            FormService填料=新FormService();
            表单域= filler.getFields();

            了request.setAttribute(用户,用户);
            了request.setAttribute(fields1字段);
            了request.setAttribute(fields2字段);
            了request.setAttribute(fields3字段);


            HttpSession的会议= request.getSession(真正的);
            //为会话设置属性
            session.setAttribute(用户,user.getUsername());

//现在,调用RequestDispatcher.forward()不转发到新的一页!
//整个search.jsp的页面被塞回login.jsp的页面

            RequestDispatcher的RD =的request.getRequestDispatcher(search.jsp的);
            rd.forward(请求,响应);
            返回;
        }
        其他{
            PrintWriter的输出= response.getWriter();
            通过out.println(登录失败!);
            返回;
        }
    }赶上(例外五){
        e.printStackTrace();
    }
}
 

但是,而不是转发请求和响应新的jsp页面search.jsp的,整个search.jsp的页面被塞回原来的login.jsp页面 - 在其中持有的Ajax responseText的html元素在当登录失败。

当servlet从表单action属性调用这个servlet的forward()方法的工作原理,但不是当servlet调用包含阿贾克斯code中的JavaScript文件。

解决方案
  

中的但是相反转发请求和响应新的jsp页面search.jsp的,整个search.jsp的页面被塞回原来的login.jsp页面 - 其中包含HTML元素阿贾克斯的responseText时登录失败

这是的的确确的预期行为。您正在操作使用JavaScript的请求/响应。你的JavaScript code已检索的 search.jsp的的响应,的responseText ,并把它在HTML元素。

您需要改变这种做法。你需要让响应返回所需的数据,充分告知的JavaScript,以便它可以处理响应正常。这样做的一个常用的数据格式是JSON。

类似于

  response.setContentType(应用/ JSON);

如果(用户!= NULL){
    // ...

    response.getWriter()写({成功:真正的,位置:search.jsp的'})。
} 其他 {
    response.getWriter()写({成功:假的,消息:未知登录'})。
}
 

在JS:

  VAR responseJson =的eval('('+ xhr.responseText +')');

如果(responseJson.success){
    了window.location = responseJson.location;
} 其他 {
    的document.getElementById(信息)的innerHTML = responseJson.message。
}
 

如果您想悄悄地处理这个问题,从而使同一个servlet是可重复使用的正常(非Ajax)的HTTP请求(让你的Web应用程序仍然在客户端的JS禁用的作品!),那么你可以,如果<$检查C $ C>的X请求 - 以头等于 XmlHTT prequest

 如果(XMLHtt prequest.equals(request.getHeader(X-要求,随着)){
    //处理Ajax响应(如返回JSON数据对象)。
} 其他 {
    //处理正常的反应(如前进和/或设置消息属性)。
}
 

参见:

I have a login form (login.jsp) with two input fields, username and password.

I am using POST via Ajax to access the login servlet.

I want the user to login, and if the login is successful, be redirected to another page called 'search.jsp'. If unsuccessful, a 'login failed' message is returned as the Ajax responseText to be inserted into a paragraph in the 'login.jsp' page.

I have everything working, my login servlet accesses the database via a separate bean, and an object of that bean is returned with its properties ready to use. So all is good to there.

But, after the username and password pass muster with the database, I'm then using RequestDispatcher to forward to the new landing page (search.jsp).

Here is my 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();
    }       
}

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.

The forward() method in the servlet works when the servlet is called from the form action attribute, but not when the servlet is called the javascript file containing the Ajax code.

解决方案

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.

That's indeed the expected behaviour. You're handling the request/response using JavaScript. Your JavaScript code has retrieved the response of search.jsp as responseText and is putting it in the HTML element.

You need to change this approach. You need to let the response return the necessary data which sufficiently informs JavaScript so that it can handle the response properly. A commonly used data format for this is JSON.

Something like

response.setContentType("application/json");

if (user != null) {
    // ...

    response.getWriter().write("{ 'success': true, 'location': 'search.jsp' }");
} else {
    response.getWriter().write("{ 'success': false, 'message': 'Unknown login' }");
}

and in JS:

var responseJson = eval('(' + xhr.responseText + ')');

if (responseJson.success) {
    window.location = responseJson.location;
} else {
    document.getElementById('message').innerHTML = responseJson.message;
}

If you want to handle this unobtrusively, so that the same servlet is reuseable on normal (non-ajax) HTTP requests (so that your webapp still works when the client has JS disabled!) then you could check if the X-Requested-With header equals to 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).
}

See also:

这篇关于JSP:调用RequestDispatcher.forward()不转发时,通过Ajax POST所谓的servlet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆