|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectfc.web.servlet.JDBCSession
public class JDBCSession
Stores session data into a database. This approach is almost always the right thing to do. Don't store session data in the servlet container memory (memory backed sessions) and don't use serialization based session persistence as implemented by various session containers. Use database sessions for storing secure and/or large amounts of data and store non-secure data directly in cookies.
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 a 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 prefix_sessiondata (
session_id varchar(50),
name varchar(100) not null,
value text -- [or some other character/text type]
);
create table prefix_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 prefix_sessiondata add
FOREIGN KEY (session_id) REFERENCES prefix_sessionmaster (session_id)
on delete cascade;
-- The following if a user table is present
alter table prefix_sessionmaster add
FOREIGN KEY (user_id) REFERENCES
NAME_OF_USER_TABLE;
The prefix for the table names is
arbitrary and must be specified in the init() for this class. 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.
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 seperate 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.
| Nested Class Summary | |
|---|---|
static class |
JDBCSession.Info
Information about a session. |
| Constructor Summary | |
|---|---|
JDBCSession()
|
|
| Method Summary | |
|---|---|
static void |
add(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key,
java.lang.String value)
Saves the tuple [sessionID, key, value] in the database. |
static void |
addAll(java.sql.Connection con,
java.lang.String sessionID,
java.util.Map data)
Adds all [key, value] pairs in the specified map to the session with the specified sessionID. |
static void |
create(java.sql.Connection con,
java.lang.String sessionID)
Creates a new session. |
static void |
create(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String userID)
Creates a new session. |
static void |
createJDBCTables(java.sql.Connection con,
java.lang.String userTableName,
java.lang.String prefix,
boolean mysql)
Creates database tables for storing session data. |
static void |
delete(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key)
Deletes both the key and value specified by the sessionID and key. |
static boolean |
exists(java.sql.Connection con,
java.lang.String sessionID)
Returns true is the specified sessionID is valid (i.e., the specified sessionID exists in the database and has not expired). |
static void |
expire(java.sql.Connection con,
java.lang.String sessionID)
Expires the session. |
static void |
expireInactiveSessions(java.sql.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. |
static java.lang.String |
get(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key)
Returns the value associated with the specified sessionID and key. |
static java.util.Map |
getAll(java.sql.Connection con,
java.lang.String sessionID)
Returns a map of all [key, value] pairs associated with the specified sessionID. |
static int |
getExpireTime()
Returns the current expire interval (seconds after which sessions can be considered eligible for removal). |
static java.util.List |
getForUser(java.sql.Connection con,
int userID)
Same as getForUser(Connection, String) but takes a numeric userID. |
static java.util.List |
getForUser(java.sql.Connection con,
java.lang.String userID)
Returns a List containing session information about all
sessions associated with the specified ID. |
static void |
init(java.lang.String prefix)
|
static void |
init(java.lang.String prefix,
Log logger)
Initializes stuff internally within this class. |
static void |
main(java.lang.String[] args)
|
static void |
put(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key,
java.lang.String value)
An alias for the #add method. |
static void |
putAll(java.sql.Connection con,
java.lang.String sessionID,
java.util.Map data)
An alias for the addAll method. |
static JDBCSession.Info |
sessionInfo(java.sql.Connection con,
java.lang.String sessionID)
Returns session information from the session master table. |
static void |
setDeleteExpiredSessions(boolean val)
By default expired sessions are deleted from the db. |
static void |
setExpireTime(int seconds)
Sessions inactive for greater than these number of seconds will be eligible for expiry. |
static void |
tieToUser(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String userID)
Associates the specified sessionID with the specified userID. |
java.lang.String |
update(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key,
java.lang.String newvalue)
Updates the value for the specified sessionID and key in the database. |
| Methods inherited from class java.lang.Object |
|---|
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
|---|
public JDBCSession()
| Method Detail |
|---|
public static void init(java.lang.String prefix)
public static void init(java.lang.String prefix,
Log logger)
prefix - arbitrary prefix to use for names of session tables
in the db. Specify null for no prefix.logger - the logging destination for methods in this class. Specify
null to use a default logger.public static void setDeleteExpiredSessions(boolean val)
public static void create(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String userID)
throws java.sql.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.
java.sql.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 static void create(java.sql.Connection con,
java.lang.String sessionID)
throws java.sql.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.
java.sql.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 static void expire(java.sql.Connection con,
java.lang.String sessionID)
throws java.sql.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.
java.sql.SQLException
public static void tieToUser(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String userID)
throws java.sql.SQLException
Note: Depending on the application, more than 1 sessionID can be associated with the same userID in the session master table.
java.sql.SQLException
public static void expireInactiveSessions(java.sql.Connection con)
throws java.sql.SQLException
setDeleteExpiredSessions(boolean)) all sessions in the database that have exceeded
the maximum inactive time.
java.sql.SQLExceptionpublic static 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 static int getExpireTime()
public static boolean exists(java.sql.Connection con,
java.lang.String sessionID)
throws java.sql.SQLException
Note: this method does not expire the session itself or check for
validity. Sessions should be expired as/when needed by calling the expire method.
java.sql.SQLException
public static JDBCSession.Info sessionInfo(java.sql.Connection con,
java.lang.String sessionID)
throws java.sql.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.
java.sql.SQLException
public static java.util.List getForUser(java.sql.Connection con,
java.lang.String userID)
throws java.sql.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.
java.sql.SQLException
public static java.util.List getForUser(java.sql.Connection con,
int userID)
throws java.sql.SQLException
getForUser(Connection, String) but takes a numeric userID.
java.sql.SQLException
public static java.util.Map getAll(java.sql.Connection con,
java.lang.String sessionID)
throws java.sql.SQLException
java.sql.SQLException
public static java.lang.String get(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key)
throws java.sql.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.
java.sql.SQLException
public static void delete(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key)
throws java.sql.SQLException
java.sql.SQLException
public static void add(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key,
java.lang.String value)
throws java.sql.SQLException
The specified sessionID must exist and be valid in the database otherwise a SQLException will be thrown.
java.sql.SQLException
public static void addAll(java.sql.Connection con,
java.lang.String sessionID,
java.util.Map data)
throws java.sql.SQLException
java.sql.SQLException
public static void put(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key,
java.lang.String value)
throws java.sql.SQLException
#add method.
java.sql.SQLException
public static void putAll(java.sql.Connection con,
java.lang.String sessionID,
java.util.Map data)
throws java.sql.SQLException
addAll method.
java.sql.SQLException
public java.lang.String update(java.sql.Connection con,
java.lang.String sessionID,
java.lang.String key,
java.lang.String newvalue)
throws java.sql.SQLException
The specified sessionID and keys must exist in the database prior to calling this method,otherwise a SQLException will be thrown.
java.sql.SQLException
public static void main(java.lang.String[] args)
throws java.lang.Exception
java.lang.Exception
public static void createJDBCTables(java.sql.Connection con,
java.lang.String userTableName,
java.lang.String prefix,
boolean mysql)
throws java.lang.Exception
java.lang.Exception
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||