By WebNest Studio Engineering Team
Advanced Java Tutorial
Session Tracking: Cookies, HttpSession, URL Rewriting
HTTP is a stateless protocol: each request is handled independently, with no built-in memory of previous requests from the same client. But real applications need to remember things across requests — who is logged in, what is in a shopping cart, what step of a checkout flow a user is on. Session tracking is the general term for the techniques Java web applications use to simulate that memory on top of stateless HTTP.
Java provides three related mechanisms, and understanding how they connect is more important than memorizing any one API: Cookies are the client-side building block, HttpSession is the server-side abstraction built on top of cookies (usually), and URL rewriting is the fallback used when cookies are unavailable.
Cookies — Client-Side State
A cookie is a small piece of data the server sends to the browser via a Set-Cookie response header; the browser stores it and automatically resends it with every subsequent request to the same domain. In servlets, you create one with new Cookie(name, value), configure it (expiry, path), and add it with response.addCookie(cookie). On later requests, request.getCookies() returns the array of cookies the browser sent back. Cookies are entirely client-managed — the server trusts what comes back, so sensitive data should never be stored directly in a cookie's value.
HttpSession — Server-Side State
HttpSession stores data on the server, keyed by a unique session ID. You obtain it with request.getSession() (creates one if it doesn't exist) or request.getSession(false) (returns null instead of creating one). You then use setAttribute() / getAttribute() to store and retrieve objects tied to that specific user's session across multiple requests. Under the hood, the container almost always uses a cookie named JSESSIONID to let the browser prove, on each request, which session it belongs to — the actual data lives in server memory (or a distributed store), not in the cookie itself.
URL Rewriting — the Fallback
If a browser has cookies disabled, the JSESSIONID cookie never gets stored, and the server would lose track of the session on the very next request. URL rewriting solves this by encoding the session ID directly into the URL instead — for example, /cart;jsessionid=ABC123. In servlet code, you never hardcode this manually; you call response.encodeURL(url) (or encodeRedirectURL() for redirects) on every outgoing link, and the container automatically appends the session ID only when it detects the client isn't using cookies. This is why every link and form action in a properly written JSP page should be wrapped in encodeURL().
Example
Tracking a logged-in user with HttpSession, with a cookie-safe link
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class DashboardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(); // creates one if none exists
Integer visitCount = (Integer) session.getAttribute("visitCount");
visitCount = (visitCount == null) ? 1 : visitCount + 1;
session.setAttribute("visitCount", visitCount);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<p>Session ID: " + session.getId() + "</p>");
out.println("<p>You have visited this page " + visitCount + " time(s).</p>");
// encodeURL appends ;jsessionid=... automatically if cookies are disabled
String logoutLink = response.encodeURL("/logout");
out.println("<a href=\"" + logoutLink + "\">Logout</a>");
out.println("</body></html>");
}
}
First visit:
Session ID: 7F3A9C1E...
You have visited this page 1 time(s).
Logout
Second visit (same browser session, cookies enabled): visit count increments to 2.
With cookies disabled: the Logout link becomes /logout;jsessionid=7F3A9C1E... to preserve the session.
Common Mistakes
- Storing sensitive information (passwords, raw credit card numbers) directly inside a cookie value, which is visible and editable on the client.
- Calling request.getSession() when you only want to check for an existing session — this creates a new empty session as a side effect if none existed; use getSession(false) to check safely.
- Forgetting to invalidate the session (session.invalidate()) on logout, leaving a valid session usable by anyone with the old session ID.
- Hardcoding links without response.encodeURL(), which silently breaks session tracking for the small fraction of users with cookies disabled.
Exercise
A teammate is about to make this mistake: Storing sensitive information (passwords, raw credit card numbers) directly inside a cookie value, which is visible and editable on the client. Use Cookies — Client-Side State to review the decision. Write a corrected implementation or design sketch that follows HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests., then name one edge case you would check.
Show hints
- Start with Cookies — Client-Side State and compare your approach with Tracking a logged-in user with HttpSession, with a cookie-safe link. Identify the decision or behavior the lesson recommends.
- Walk through your scenario step by step. Confirm that it follows HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests. and that it would catch the failure described by Storing sensitive information (passwords, raw credit card numbers) directly inside a cookie value, which is visible and editable on the client..
Quick quiz
1. Which choice best describes the recommended approach in Session Tracking: Cookies, HttpSession, URL Rewriting?
- A. Storing sensitive information (passwords, raw credit card numbers) directly inside a cookie value, which is visible and editable on the client.
- B. Calling request.getSession() when you only want to check for an existing session — this creates a new empty session as a side effect if none existed; use getSession(false) to check safely.
- C. HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests.
Show answer
C. This is the recommended approach: HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests. Avoid: Storing sensitive information (passwords, raw credit card numbers) directly inside a cookie value, which is visible and editable on the client.
Interview questions
Why does this principle matter in Session Tracking: Cookies, HttpSession, URL Rewriting: HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests.
Show answer
HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests. Apply this in Cookies — Client-Side State; the example Tracking a logged-in user with HttpSession, with a cookie-safe link shows one way to do it. Avoid Storing sensitive information (passwords, raw credit card numbers) directly inside a cookie value, which is visible and editable on the client. and explain how your implementation or design prevents that failure.
Key Points to Remember
- HTTP is stateless; cookies, HttpSession, and URL rewriting are the mechanisms Java web apps use to fake state across requests.
- Cookies are client-side and container-agnostic; the container typically uses a JSESSIONID cookie to link a browser to server-side session data.
- HttpSession stores data on the server, accessed via getSession(), setAttribute(), and getAttribute().
- URL rewriting (via response.encodeURL()) is the fallback session-tracking mechanism when the client has cookies disabled.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
These examples need a JDK project with their libraries on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering