Java – HTTP Session: A single object or multiple

httphttp-requestjavasession

I tested two approaches to store session data:

  • The classic: 1 key, 1 object (And every key as static final String in a class)

"user" –> UserObject

"preferences" –> List

  • An approach with only 1 object

"sessionObject" –> SessionObject

And my SessionObject contains UserObject and the list of preferences as attributes. This is a fairly simple example but imagine it with 20+ attributes.

The advantage I see in the second approach is that :

  • You only have to delete one key to ensure session is empty
  • You don't have to create the bothersome set of final static String to create the keys
  • You'll know what type of object to retrieve (Using key you have to cast)

Do you see any problem I might went over? Or does anything go against best practices?

Best Answer

1 key, 1 object will be more predictable regarding interaction with app server and possible session replication techniques. Not sure what you mean by "set of final static String" being necessary. You may manage session keys any way you like.

Consider you have 20 preferences, and perhaps your preferences class has an enum of preference names. Could get/set session a little bit indirectly:

class Preferences {

    private static final SESSION_KEY_PREFIX = Preferences.class.getName()+'.';

    enum Name {
        LOCALE,
        ...
    }

    static String get(HttpSession session, Name name) {
        return (String)session.getAttribute(SESSION_KEY_PREFIX + name.name());
    }

    static void set(HttpSession session, Name name, String value) {
        session.setAttribute(SESSION_KEY_PREFIX + name.name(), value);
    }

    static void clear(HttpSession session) {
        for(Name name : Name.values()) {
            session.removeAttribute(SESSION_KEY_PREFIX + name.name());
        }
    }
}

You may then add preferences by just adding to the enum, and all specific interaction with the session is encapsulated.

This example pretty trivial so the Preferences class itself could also become an enum instead, without a separate "Name" enum. Which could be:

enum Preference {
    LOCALE,
    ....;

    private final String sessionKey = Preference.class.getName()+'.'+name();

    String get(HttpSession session) {
        return (String)session.getAttribute(sessionKey);
    }

    void set(HttpSession session, String value) {
        session.setAttribute(sessionKey, value);
    }

    static void clear(HttpSession session) {
        for(Preference pref : Preference.values()) {
            session.removeAttribute(pref.sessionKey);
        }
    }
}