Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Session attribute is lost after invoking a client-side redirect

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.

like image 497
S.C. Avatar asked Oct 12 '15 07:10

S.C.


1 Answers

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.

like image 189
Ish Avatar answered Oct 03 '22 15:10

Ish