public final class JDBCSession extends Object
Database sessions enable front-end webservers to scale easily. (No messy/brittle session migration hacks are required !). Scaling can be near infinite, but after a point (say 100 front ends), the back-end databases may also have to be partitioned (and the appropriate partition/machine invoked for a given session-id).
Note, memory sessions are not needed even for maintaining html form-state
because each form's state can be uniquely created from an initial form
state (common to all users) along with the per-usr data submitted per
request. This is exactly how the form
API works.
However, memory sessions are useful for certain transient things/caches
or for very quick'n'dirty apps, where using a database is more trouble
than it's worth.
Given fast ethernet connections and forward marching processor/peripheral speeds, JDBC session data is typically retrieved on the order of 1-2 milliseconds (or even lesser).
Using this class requires the following database table schema in the database:
create table sessiondata ( session_id varchar(50), name varchar(100) not null, value text -- [or some other character/text type] ); create table sessionmaster ( session_id varchar(50) primary key, -- the session id created timestamp not null, -- session create time accessed timestamp not null, -- session last accessed is_expired bool default 'f', -- true if expired -- a reference to the user table that associates a user_id -- with one or more session_id's. Optional so should be -- nullable if used. user_id <SQL_TYPE_FROM_YOUR_USER_TABLE> ); alter table sessiondata add FOREIGN KEY (session_id) REFERENCES sessionmaster (session_id) on delete cascade; -- The following if a user table is present alter table sessionmaster add FOREIGN KEY (user_id) REFERENCES NAME_OF_USER_TABLE;
When creating these tables, it is also advisable to index the session_id and user_id columns for faster performance.
The above tables can also be created by this class itself. Invoke the main method without any arguments to see usage information. The table names sessionmaster and sessiondata come from final static variables in this class. If you want to use different names, change these variables and recompile this class.
More than one [name, value] pair can be stored in the sessiondata table. This class will automatically store [name, value] pairs as seperate rows and can return a particular [name, value] pair or all [name, value] pairs for the specified session.
Note: This class allows saving data only as Strings/text. However, arbitrary binary data can also be stored but the caller should first base64 encode that data and then save it as a string. Upon retrieval, that data can be base64 decoded.
Note 2: Under some scenarios, it is important to have a separate cleaner process that periodically deletes expired sessions from the database. This process should run via cron, some other stand-alone java code etc., and should delete sessions which are marked expired or whose create_time - last_used_time is greater than the session expiry time. Under other scenarios, sessions may be deleted after a set amount of time from the creation data regardless of when the session was last accessed.
Note 3: Typically, expired session data is simply deleted from the session
tables in the database. (for example, amazon.com users have to persist
their cart manually by clicking on a "save-for-later" button - which moves
data to more persistent tables -- otherwise their cart session is deleted
from the database when the session expires). It is however possible that
instead of deleting sessions, the sessions are instead marked as "expired"
but not deleted from the database. (this is done via the setDeleteExpiredSessions(boolean)
method.
Modifier and Type | Class and Description |
---|---|
static class |
JDBCSession.Info
Information about a session.
|
Modifier and Type | Field and Description |
---|---|
static String |
SESSIONDATA_TABLE |
static String |
SESSIONMASTER_TABLE |
Modifier and Type | Method and Description |
---|---|
void |
add(Connection con,
String sessionID,
String key,
String value)
Saves the tuple [sessionID, key, value] in the database.
|
void |
addAll(Connection con,
String sessionID,
Map data)
Adds all [key, value] pairs in the specified map to the session with the
specified sessionID.
|
void |
create(Connection con,
String sessionID)
Creates a new session.
|
void |
create(Connection con,
String sessionID,
String userID)
Creates a new session.
|
static void |
createJDBCTables(Connection con,
String userTableName,
boolean mysql)
Creates database tables for storing session data.
|
void |
delete(Connection con,
String sessionID,
String key)
Deletes both the key and value specified by the sessionID and key.
|
boolean |
exists(Connection con,
String sessionID)
Returns true is the specified sessionID is valid (i.e., the specified
sessionID exists in the database and has not expired).
|
void |
expire(Connection con,
String sessionID)
Expires the session.
|
void |
expireInactiveSessions(Connection con)
Utility method that deletes (or marked as expired depending on
setDeleteExpiredSessions(boolean) ) all sessions in the database that have exceeded
the maximum inactive time. |
String |
get(Connection con,
String sessionID,
String key)
Returns the value associated with the specified sessionID and key.
|
Map |
getAll(Connection con,
String sessionID)
Returns a map of all [key, value] pairs associated with the specified
sessionID.
|
int |
getExpireTime()
Returns the current expire interval (seconds after which
sessions can be considered eligible for removal).
|
List |
getForUser(Connection con,
int userID)
Same as
getForUser(Connection, String) but takes a numeric userID. |
List |
getForUser(Connection con,
String userID)
Returns a List containing
session information about all
sessions associated with the specified ID. |
static JDBCSession |
getInstance()
Returns an instance of JDBCSession.
|
static JDBCSession |
getInstance(Log logger)
Returns an instance of JDBCSession.
|
static void |
main(String[] args) |
void |
put(Connection con,
String sessionID,
String key,
String value)
An alias for the
#add method. |
void |
putAll(Connection con,
String sessionID,
Map data)
An alias for the
addAll method. |
JDBCSession.Info |
sessionInfo(Connection con,
String sessionID)
Returns session information from the session master table.
|
void |
setDeleteExpiredSessions(boolean val)
By default expired sessions are deleted from the db.
|
void |
setExpireTime(int seconds)
Sessions inactive for greater than these number of seconds will be
eligible for expiry.
|
void |
tieToUser(Connection con,
String sessionID,
String userID)
Associates the specified sessionID with the specified userID.
|
String |
update(Connection con,
String sessionID,
String key,
String newvalue)
Updates the value for the specified sessionID and key in the database.
|
public static final String SESSIONDATA_TABLE
public static final String SESSIONMASTER_TABLE
public static JDBCSession getInstance()
public static JDBCSession getInstance(Log logger)
logger
- the logging destination for methods in this class. Specify
null to use a default logger.public void setDeleteExpiredSessions(boolean val)
public void create(Connection con, String sessionID, String userID) throws SQLException
con
- a jdbc connectionsessionID
- value for sessionID, the SessionUtil.newSessionID()
can be used to generate this. Should not be null. It is
not recommended that the servlet container
generated jsession_id cookie be used for this
value. This sessionID is then later used to retrieve and
work with the created session and this sessionID will
typically be stored as a cookie or URL encoded on the
client.userID
- a userID to associate with this session. Note,
userID's in user tables are typically auto generated
numerical sequences. Stringify numerical values before
passing them into this method. This value should
not be null, otherwise a runtime
exception will be thrown.SQLException
- if a SQL error occurs. Note, also thrown if the
session_id already exists in the database (since all
session_id's must be unique).public void create(Connection con, String sessionID) throws SQLException
tieToUser(java.sql.Connection, java.lang.String, java.lang.String)
method.
Note, sessionID's are typically be stored as a cookie or URL encoded on the client and are thus unique per browser/client). A user is not required to login to have session data.
con
- a jdbc connectionsessionID
- value for sessionID, the SessionUtil.newSessionID()
can be used to generate this. Should not be null. It is
not recommended that the servlet container
generated jsession_id cookie be used for this
value. This sessionID is then later used to retrieve and
work with the created session.SQLException
- if a SQL error occurs. Note, also thrown if the
session_id already exists in the database (since all
session_id's must be unique).public void expire(Connection con, String sessionID) throws SQLException
deleteExpiredSessions
is set to true, then the session is marked
as expired in the database but the rows are not deleted from the db.
Either way, after this method returns, the sessionID will not longer be valid.
SQLException
public void tieToUser(Connection con, String sessionID, String userID) throws SQLException
Note: Depending on the application, more than 1 sessionID can be associated with the same userID in the session master table.
SQLException
public void expireInactiveSessions(Connection con) throws SQLException
setDeleteExpiredSessions(boolean)
) all sessions in the database that have exceeded
the maximum inactive time.SQLException
public void setExpireTime(int seconds)
Note: these expired sessions will still not
be expired until the expireInactiveSessions()
method is invoked.
Defaults to 8 hours (=60*60*8 seconds)
public int getExpireTime()
public boolean exists(Connection con, String sessionID) throws SQLException
Note: this method does not expire the session itself or check for
non-expired validity. Sessions should be expired as/when needed by calling the
expire
method.
SQLException
public JDBCSession.Info sessionInfo(Connection con, String sessionID) throws SQLException
info
object encapsulating the master
row for the given sessionID. Returns null if the given sessionID has expired and/or was not found in the database.
SQLException
public List getForUser(Connection con, String userID) throws SQLException
session information
about all
sessions associated with the specified ID. Returns an empty list if no
sessions are found for the specified userID.
Note, the specified userID can be null in which case all sessions with null userID's will be returned.
SQLException
public List getForUser(Connection con, int userID) throws SQLException
getForUser(Connection, String)
but takes a numeric userID.SQLException
public Map getAll(Connection con, String sessionID) throws SQLException
null
if the specified sessionID is not found
in the database or if the specified session has expired.SQLException
public String get(Connection con, String sessionID, String key) throws SQLException
Returns null if the specified session has expired, or the specified key does not exist in the database or exists but contains a null in the database.
SQLException
public void delete(Connection con, String sessionID, String key) throws SQLException
SQLException
public void add(Connection con, String sessionID, String key, String value) throws SQLException
The specified sessionID must exist and be valid in the database otherwise a SQLException will be thrown.
SQLException
public void addAll(Connection con, String sessionID, Map data) throws SQLException
SQLException
public void put(Connection con, String sessionID, String key, String value) throws SQLException
#add
method.SQLException
public void putAll(Connection con, String sessionID, Map data) throws SQLException
addAll
method.SQLException
public String update(Connection con, String sessionID, String key, String newvalue) throws SQLException
The specified sessionID and keys must exist in the database prior to calling this method,otherwise a SQLException will be thrown.
SQLException
public static void createJDBCTables(Connection con, String userTableName, boolean mysql) throws Exception
Exception