LoginSignup
0
0

More than 1 year has passed since last update.

Note of Java Servlet session

Posted at

API

A Java Servlet (Servlet) application uses API methods below to access session related function.

package javax.servlet.http;

public interface HttpServletRequest extends ServletRequest {
    public HttpSession getSession(boolean create);
    public HttpSession getSession();
    public String changeSessionId();
    public String getRequestedSessionId();
    public boolean isRequestedSessionIdValid();
    public boolean isRequestedSessionIdFromCookie();
    public boolean isRequestedSessionIdFromURL();
    @Deprecated
    public boolean isRequestedSessionIdFromUrl();
    ...
}
  • These methods are implemented by Servlet container (e.g. Tomcat)
  • Session object has interface javax.servlet.http.HttpSession, and normally its lifecycle is maintainanced by Servlet container. In Tomcat it is org.apache.catalina.session.StandardSession, wrapped by org.apache.catalina.session.StandardSessionFacade

Association between HTTP connection and session object

HTTP is stateless protocol, when Servlet application needs to store something into session object, it calls following methods to retrieve it.

javax.servlet.http.HttpServletRequest.getSession();
// or
javax.servlet.http.HttpServletRequest.getSession(true);

Servlet container instantiates session object, creates session id and associates it with HTTP connection by writing session cookie information (default identifier is JSESSIONID).

Set-Cookie: JSESSIONID=14AE061861E1F5979F28A3D5D742A850; Path=/; HttpOnly

The implementation of Tomcat 9 is org.apache.catalina.connector.Request#doGetSession. Writing
session cookie is performed by following code

        // Creating a new session cookie based on that session
        if (session != null && trackModesIncludesCookie) {
            Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie(
                    context, session.getIdInternal(), isSecure());

            response.addSessionCookieInternal(cookie);
        }

org.apache.catalina.connector.Response#addSessionCookieInternal is called

    /**
     * Special method for adding a session cookie as we should be overriding
     * any previous.
     *
     * @param cookie The new session cookie to add the response
     */
    public void addSessionCookieInternal(final Cookie cookie) {
        if (isCommitted()) {
            return;
        }

        String name = cookie.getName();
        final String headername = "Set-Cookie";
        final String startsWith = name + "=";
        String header = generateCookieString(cookie);
        boolean set = false;
        MimeHeaders headers = getCoyoteResponse().getMimeHeaders();
        int n = headers.size();
        for (int i = 0; i < n; i++) {
            if (headers.getName(i).toString().equals(headername)) {
                if (headers.getValue(i).toString().startsWith(startsWith)) {
                    headers.getValue(i).setString(header);
                    set = true;
                }
            }
        }
        if (!set) {
            addHeader(headername, header);
        }
    }

In next HTTP request, the session id is provided in cookie header

GET /login HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:8080/
Connection: keep-alive
Cookie: JSESSIONID=14AE061861E1F5979F28A3D5D742A850
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin

The application gets saved data by retrieving session object, calls

javax.servlet.http.HttpServletRequest.getSession();
// or
javax.servlet.http.HttpServletRequest.getSession(false);

In Tomcat 9 retrieves session object is also processed by org.apache.catalina.connector.Response#addSessionCookieInternal. Following code is for loading session object

        // Return the requested session if it exists and is valid
        Manager manager = context.getManager();
        if (manager == null) {
            return null;      // Sessions are not supported
        }
        if (requestedSessionId != null) {
            try {
                session = manager.findSession(requestedSessionId);
            } catch (IOException e) {
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("request.session.failed", requestedSessionId, e.getMessage()), e);
                } else {
                    log.info(sm.getString("request.session.failed", requestedSessionId, e.getMessage()));
                }
                session = null;
            }
            if ((session != null) && !session.isValid()) {
                session = null;
            }
            if (session != null) {
                session.access();
                return session;
            }
        }

Other API calls

// change session id, but session object created in Servlet container will not be destroyed
javax.servlet.http.HttpServletRequest.changeSessionId();

// Unassociate current session object
javax.servlet.http.HttpSession.invalidate();
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0