Issue
I am practicing maintaining sessions between client and server. For that I used simple solution with JSESSIONID stored inside cookie. So my little program works like this:
index.html:
<html><body>
<form action="testing">
<input type="text" name="animal">
<button>Go</button>
</form>
</body></html>
MyServlet.java (mapped in XML as /testing):
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
String name = req.getParameter("animal");
PrintWriter pw = resp.getWriter();
pw.print("Welcome " + name + "<br>");
HttpSession session = req.getSession();
if (session.isNew()) {
pw.print("New session: " + session.getId() + "<br>");
} else {
pw.print("Old session: " + session.getId() + "<br>");
}
pw.print("<a href=\'index.html\'> Home </a>");
}
}
So, if I submit something from FORM more than twice, Server should "find" my JSESSIONID stored in heap. Here is a picture of how it would look when FORM is submitted (I typed 'parrot' inside input):
But then I disabled cookies in my browser. After, my server never finds user's JSESSIONID because user never actually stores it anywhere. Remember that before, JSESSIONID was stored in a cookie, but since I disabled them, it can't possibly store it there anymore. So now, I am stuck.
What can I do in this case? I came across response.encodeURL()
that uses URL and appends its JSESSIONID into URL. But I have trouble understanding how to implement it and how it works internally. Can someone tell me how to fix this using encodeURL()
and actually explain how does code work after made such implementation?
Solution
As per the specification, the server should support a few ways of tracking sessions: with cookies, SSL sessions, or URL rewriting.
You are asking about URL rewriting, which works like this:
URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basis for session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.
The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:
http://www.myserver.com/catalog/index.html;jsessionid=1234
URL rewriting exposes session identifiers in logs, bookmarks, referer headers, cached HTML, and the URL bar. URL rewriting should not be used as a session tracking mechanism where cookies or SSL sessions are supported and suitable.
Notice that it's a path parameter, not a query parameter. Your query params will follow that, like this:
http://www.myserver.com/catalog/index.html;jsessionid=1234?param1=value1¶m2=value2&...
This mechanism is supported automatically by the server to track sessions, but it becomes pretty obvious that you need to give the server a helping hand. And you do that by making sure that all your links include the jsessionid
otherwise your server won't identify your request with a session.
You can use encodeURL
in your Java code:
Encodes the specified URL by including the session ID, or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL encoding is unnecessary.
For robust session tracking, all URLs emitted by a servlet should be run through this method. Otherwise, URL rewriting cannot be used with browsers which do not support cookies.
You need to do the same inside your JSP files. That's usually done with something like <c:url>
instead of writing URLs directly into the file:
[...] You can use the url tag to rewrite URLs returned from a JSP page. The tag includes the session ID in the URL only if cookies are disabled; otherwise, it returns the URL unchanged. Note that this feature requires that the URL be relative. [...]
Answered By - Bogdan