URL Rewriting & Session Tracking
URL Rewriting & Session Tracking
HTTP is a stateless protocol: each request stands alone and the server retains nothing between calls. Sessions give the illusion of continuity, but they require the browser and server to exchange a token on every request so the server can look up the right HttpSession object. The standard token is a cookie named JSESSIONID. But cookies can be disabled — by the browser, by the user, or by a corporate proxy. When that happens the server falls back to URL rewriting, embedding the session token directly in every link and form action as a query parameter or path segment.
How the Container Tracks Sessions
The Jakarta Servlet specification defines three session-tracking modes that can be combined:
- COOKIE — the container sets a
Set-Cookie: JSESSIONID=<token>; HttpOnly; Path=/header on the first response and the browser returns it automatically on every subsequent request. - URL — the token is appended to URLs as
;jsessionid=<token>, for example/app/dashboard;jsessionid=ABC123. This works even when cookies are blocked. - SSL — the session is tied to the TLS session ID (rarely used in practice).
The container negotiates automatically: it sends the cookie on the first response and checks on the next request whether the cookie came back. If the cookie is absent (either never sent or deleted), it falls through to URL rewriting.
HttpServletResponse.encodeURL(String url) and HttpServletResponse.encodeRedirectURL(String url). If the container determines the client accepts cookies, these methods return the URL unchanged. If cookies are not yet confirmed or are absent, they append ;jsessionid=.... Always call them — at worst they are a no-op.
encodeURL in Practice
Every hyperlink and form action in a server-rendered page should be wrapped with encodeURL:
When cookies are active the output is simply /app/profile. When cookies are disabled the output becomes /app/profile;jsessionid=A7F3D2C1B8E94560. The HTML is otherwise identical — your code stays portable.
Redirects Need encodeRedirectURL
encodeURL is for links in HTML. encodeRedirectURL is for the Location header sent with a redirect. Use the right method for the right context:
req.getContextPath() when building URLs. Hard-coding /app/... breaks the moment the application is deployed at a different context root. getContextPath() returns the correct prefix — empty string for a root deployment, /myapp otherwise.
Session Tracking Mode Configuration
You can restrict or control tracking modes in web.xml to enforce a security policy:
Or programmatically during application startup:
Referer header sent to third-party sites, server access logs, and shared bookmarks. For most production applications you should enforce COOKIE-only tracking and require HTTPS, making the token invisible outside the encrypted channel.
JSP and JSTL: c:url Handles This For You
When you write views in JSP, the JSTL <c:url> tag automatically calls encodeURL internally so you never have to remember:
This is one of the reasons JSP/JSTL views are still preferred over manually constructing HTML in servlet code — session management boilerplate is handled transparently.
How the Container Parses the Incoming Session ID
On every incoming request request.getSession() (and its variants) trigger the following internal sequence:
- Check the
Cookieheader forJSESSIONID. - If absent, check the request URI for
;jsessionid=<token>. - Look up the token in the session store (memory, database, Redis, etc.).
- Return the
HttpSessionif found and not expired; otherwise create a new one (ifgetSession(true)) or returnnull(ifgetSession(false)).
You can inspect which mechanism delivered the current session:
Summary
URL rewriting is the servlet container's fallback mechanism for session continuity when cookies are unavailable. The two key methods are encodeURL for hyperlinks and encodeRedirectURL for redirect responses — always call them so your application works in both cookie and cookie-less environments. For production, enforce COOKIE-only tracking with HttpOnly and Secure flags to keep session tokens out of logs and browser history. When writing JSP views, let <c:url> handle the encoding for you.