HTTP does not remember earlier requests. HttpSession gives the server a per-client state container and associates later requests with it through a session identifier, usually carried in a cookie. The cookie contains an opaque identifier, while application values such as the user id or cart state remain on the server.
A secure session design creates state only when needed, rotates the identifier after authentication, stores the smallest useful values, expires inactive sessions, and invalidates the session during logout. It must also handle clients that reject cookies without exposing identifiers carelessly.
getSession() returns the current session or creates one. getSession(false) returns the current session or null and is the right choice for endpoints that should not create anonymous state. setAttribute() binds an application object to a name; getAttribute() returns it or null; invalidate() ends the session and unbinds its attributes.
Session attributes may be accessed by concurrent requests from the same browser, so mutable objects stored in a session need careful design. Prefer small immutable identifiers and load current business data from an authoritative service rather than storing an entire editable domain object for hours.
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
@WebServlet("/account/*")
public class AccountServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
if ("/login".equals(req.getPathInfo())) {
// Validate credentials before this point.
HttpSession session = req.getSession(true);
req.changeSessionId();
session.setAttribute("userId", 42L);
session.setMaxInactiveInterval(30 * 60);
resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
return;
}
HttpSession session = req.getSession(false);
if (session != null) session.invalidate();
resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
}
Containers commonly transport the session id in a cookie such as JSESSIONID. Configure the session cookie as HttpOnly so scripts cannot read it, Secure so it is sent only over HTTPS, and with an appropriate SameSite policy at the server or deployment layer. These settings reduce exposure but do not replace authorization or CSRF protection.
Never put a password, access token, personal profile, or serialized application state into the session-id cookie. A stolen valid identifier can let another client act as the session owner until the session expires or is invalidated.
@WebServlet("/cookie-demo")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// ===== Create Cookie =====
Cookie userCookie = new Cookie("username", "Alice");
userCookie.setMaxAge(7 * 24 * 60 * 60); // 7 days
userCookie.setPath("/");
userCookie.setHttpOnly(true); // Prevent XSS
userCookie.setSecure(true); // HTTPS only
resp.addCookie(userCookie);
// ===== Read Cookies =====
Cookie[] cookies = req.getCookies();
String username = null;
if (cookies != null) {
for (Cookie c : cookies) {
if ("username".equals(c.getName())) {
username = c.getValue();
break;
}
}
}
// ===== Delete Cookie =====
Cookie deleteCookie = new Cookie("username", "");
deleteCookie.setMaxAge(0); // Expire immediately
deleteCookie.setPath("/");
// resp.addCookie(deleteCookie); // Uncomment to delete
// ===== URL Rewriting (fallback when cookies disabled) =====
String encodedUrl = resp.encodeURL(req.getContextPath() + "/profile");
// Appends ;jsessionid=... if cookies are disabled
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<p>Username from cookie: " + username + "</p>");
out.println("<a href='" + encodedUrl + "'>My Profile</a>");
}
}
Session fixation happens when an attacker causes a victim to authenticate while using an identifier already known to the attacker. After successful authentication or another major privilege change, call changeSessionId() so the authenticated session uses a fresh identifier while its attributes remain available.
Logout should invalidate server-side state, clear authentication cookies as appropriate, and avoid redirects to attacker-controlled locations. Password changes, account recovery, and administrator impersonation flows may also justify rotating or revoking sessions.
If cookie-based tracking is unavailable, a servlet container can encode the session identifier into application URLs. Pass internal links through response.encodeURL() and redirects through encodeRedirectURL(); the container decides whether rewriting is necessary.
URL-based identifiers can leak through browser history, copied links, logs, analytics, and Referer headers. Prefer secure cookies, avoid URL rewriting for sensitive applications when possible, and never hand-build a ;jsessionid value.
String cartUrl = resp.encodeURL(req.getContextPath() + "/cart");
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().printf("<a href=\"%s\">Cart</a>", cartUrl);
Try this next
0 of 3 completed
No. HttpSession is server-managed state; a cookie commonly transports the opaque identifier that links a request to that state.
The session becomes invalid and its bound attributes are removed. A later getSession() call can create a different session.
No. Store compact serializable state and obtain short-lived infrastructure resources from managed services or pools.
Explore 500+ free tutorials across 20+ languages and frameworks.