I would like to create an endpoint/servlet in tomcat to expose the state of an HttpSession -- basically how long until it expires -- for the sake of giving the user a warning that they will be logged out soon. (It would be called queried from javascript on the client, in order to determine if a warning should be given.)
However, merely calling request.getSession(false)
extends the session to its full time, making the call pointless.
How can I discover the state of the session without having it count as "activity" on the session?
Keeping track with a client-side timer is failing us, as users often open more than one tab to the application, which extends the session through activity, making the timer incorrect.
I would like to create an endpoint/servlet in tomcat to expose the state of an HttpSession -- basically how long until it expires -- for the sake of giving the user a warning that they will be logged out soon. (It would be called queried from javascript on the client, in order to determine if a warning should be given.)
However, merely calling request.getSession(false)
extends the session to its full time, making the call pointless.
How can I discover the state of the session without having it count as "activity" on the session?
Keeping track with a client-side timer is failing us, as users often open more than one tab to the application, which extends the session through activity, making the timer incorrect.
Share Improve this question asked Mar 24 at 23:56 MumonkanMumonkan 1411 gold badge1 silver badge6 bronze badges 01 Answer
Reset to default 1The servlet uses Tomcat's internal Manager
and Session
classes to retrieve session metadata without updating the last accessed time. The session ID is obtained directly from the cookie to avoid creating a new session via request.getSession()
import .apache.catalina.Manager;
import .apache.catalina.Session;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/session-expiry")
public class SessionExpiryServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// Get the session ID from the cookie without creating a new session
String sessionId = getSessionIdFromCookie(request);
if (sessionId == null) {
respondWithNoSession(response);
return;
}
// Access Tomcat's Manager to retrieve session metadata
Manager manager = getTomcatManager(request);
if (manager == null) {
respondWithError(response, "Not running on Tomcat");
return;
}
Session tomcatSession = manager.findSession(sessionId);
if (tomcatSession == null) {
respondWithSessionExpired(response);
return;
}
// Calculate remaining time without touching the session's last access
long remainingTime = calculateRemainingTime(tomcatSession);
sendResponse(response, remainingTime);
}
private String getSessionIdFromCookie(HttpServletRequest request) {
String cookieName = request.getServletContext().getSessionCookieConfig().getName();
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
}
return null;
}
private Manager getTomcatManager(HttpServletRequest request) {
try {
return ((.apache.catalina.core.ApplicationContext) request.getServletContext()).getManager();
} catch (ClassCastException e) {
return null; // Not running on Tomcat
}
}
private long calculateRemainingTime(Session session) {
long lastAccessed = session.getLastAccessedTime();
int maxInactive = session.getMaxInactiveInterval() * 1000; // Convert seconds to ms
long currentTime = System.currentTimeMillis();
return (lastAccessed + maxInactive) - currentTime;
}
private void sendResponse(HttpServletResponse response, long remainingTime) throws IOException {
response.setContentType("text/plain");
response.getWriter().print(remainingTime);
}
}