9

Previously, the servlet uses response.sendRedirect("pages/my_page.jsp?foo=bar"); without problem. Session attributes can be retrieved in the subsequent pages being redirected to.

Currently, I am changing the way to send requests. Originally, the Javascript uses myForm.submit();, but I have now changed it to jQuery.ajax("my_page.jsp?foo=bar", {...});. Then, the servlet includes a URL in the JSON response instead of response.sendRedirect(), and in the success function, I use window.location.replace(url); to navigate to the new page. However, the saved session attributes cannot be fetched in subsequent pages.

I have compared the session IDs by inserting <%= session.getId() %> in my JSP pages. They are the same. The issue here is session.getAttribute("myAttribute_1") returns null in the page redirected to.

I am not sure if this matters, but I am in fact doing this task with more than 1 JSP pages:

A.jsp --- (redirect) ---> B.jsp --- (redirect) ---> C.jsp

In this case, how can I get the saved session attributes in C.jsp?


Edit

Below is the code snippet I use to save session attribute.

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession(true);

    response.setContentType("application/json");

    CustomObject customObject = new CustomObject();
    // ...
    session.setAttribute("myAttribute_1", customObject);

    PrintWriter writer = response.getWriter();
    JsonObject json = new JsonObject();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    json.addProperty("url", "next_page.jsp?foo=bar");
    writer.println(gson.toJson(json));
    writer.close();
}

Below is the code snippet for redirecting.

function redirectHandler(data, currentUrl) {
    if (data && data.hasOwnProperty('url')) {
        var redirectUrl = data.url;
        jQuery.get(redirectUrl).done(function(response) {
            redirectHandler(response, redirectUrl);
        });
    } else {
        window.location.replace(currentUrl);
    }
}

function sendFormData(method, url, form) {
    jQuery.ajax(url, {
        'method': method,
        'data': parseData(jQuery(form).serializeArray()),
        'success': function(data) {
            redirectHandler(data, window.location.href);
        }
    });
}

Result

I have reverted back to using response.sendRedirect("pages/my_page.jsp?foo=bar") in my servlet.

On the client side, jQuery.ajax() is removed and the function sendFormData() is updated as follows.

function sendFormData(form) {
    var data = parseData(jQuery(form).serializeArray());
    var f = document.createElement('form');

    for (var key in data) {
        jQuery('<input>').attr({
            'type': 'hidden',
            'name': key,
            'value': data[key]
        }).appendTo(f);
    }

    f.setAttribute('method', form.getAttribute('method'));
    f.setAttribute('action', form.getAttribute('action'));
    f.submit();
}

Whenever I want to submit a form, a click event handler is attached. It will call sendFormData(myOriginalForm); rather than myOriginalForm.submit(); as I need to customize the data to be sent.

Only by applying these simple changes, everything works again.

Still, I am looking for an explanation on this weird behavior.

S.C.
  • 850
  • 10
  • 35
  • can you please post code where you actually saved Attribute into session with attribute named - "myAttribute_1" ? – Vishal Gajera Oct 12 '15 at 08:09
  • @Mr.VishalJGajera There you are. – S.C. Oct 12 '15 at 08:15
  • if possible then post whole code from where to where you are calling ? i am think that you did some little bit mistake, but can not sure so that code needed. – Vishal Gajera Oct 12 '15 at 08:15
  • @Mr.VishalJGajera Code updated. – S.C. Oct 12 '15 at 08:33
  • Okay, code looks fine. Also another doubt, can you show me flow from where to where gone into 1-line. like, a.jsp ---> Servlet.java ---> newjsp.jsp, Also check as per you thinking flow goes perfectly likewise, also debug code for checking flow as per your wish. – Vishal Gajera Oct 12 '15 at 08:37
  • @Mr.VishalJGajera I have included the JS code for redirecting pages. – S.C. Oct 12 '15 at 08:52
  • upload whole code at some Repo. will provide you whole solution.Because i can not exactly identify. so if possible then do it. – Vishal Gajera Oct 12 '15 at 08:53
  • @Mr.VishalJGajera Nevermind then. It is something private so I cannot upload everything. – S.C. Oct 12 '15 at 08:59
  • Most likely it is duplicate: http://stackoverflow.com/questions/2870371/why-is-jquerys-ajax-method-not-sending-my-session-cookie – sibnick Oct 18 '15 at 15:33
  • @sibnick But I am redirecting to pages in the same domain... – S.C. Oct 19 '15 at 02:07
  • But it is important that script (jquery) domain should be from your server. – sibnick Oct 21 '15 at 06:22
  • @sibnick Yes, the JSP pages, Javascript files, and Java servlet are all on the same server. – S.C. Oct 21 '15 at 07:06

2 Answers2

3

Have you tried different forms of Javascript redirects?

Recommended approach is:

window.location.href=currentUrl;

According to this article, using window.location.replace will replace the current session.

Ish
  • 3,460
  • 1
  • 14
  • 20
  • Could you not redirect and pass reference information as well, so you can then create the new session once the redirect is on the new address? – Steven Scott Oct 18 '15 at 17:44
  • @StevenScott I could see the JSESSIONID being sent with ajax, only several attributes in the original session were lost. Creating new session is not a viable solution in my case. – S.C. Oct 19 '15 at 02:10
2

On the server side

HTTP requests are stateless and the sessions are laid on top of HTTP by different means like

  • URL rewriting (e.g. server starts new session and returns its ID to the client, then client appends session id to all subsequent requests http://host:port/path;session_id=12345)
  • cookies (e.g upon session creation server responds with a cookie encoding session ID, and on the server side you expect that cookie to correlate each request with existing session).

It is the client's responsibility to ensure that they participate in the session by the means expected by the server. When the server is implemented using Java Servlet API it is either jsessionid cookie or the query parameter with the same name appended to the URL, which identifies the session id.

If the client does not support cookies, using Java Servlet API you will have to redirect to a URL created by HttpServletResponse.encodeRedirectURL(String url).

In order to redirect from a servlet use HttpServletResponse.sendRedirect(String url);.

Responding form the server with standard for HTTP redirects will simplify your design. Jquery does implement these standards and therfore will honour HTTP 301 and 302 responses from the server as ilustrated here so no redirect logic on the client side should be needed.


On the client side

Your client is jquery and its ajax implementation will respect and replay the cookies set for any given domain, when subsequent request will be made to the same domain.

If you are redirecting to a different domain, for jquery to work with CORS sessions, please add xhrFields to your request:

$.ajax({
    url: a_cross_domain_url,
    xhrFields: {
      withCredentials: true
    }
});

as per this answer

Community
  • 1
  • 1
diginoise
  • 6,666
  • 1
  • 25
  • 32
  • If the domain is omitted from the URL in my ajax call, does it count as a cross domain request? – S.C. Oct 21 '15 at 07:07