Class SessionModule
- java.lang.Object
-
- com.google.inject.AbstractModule
-
- ratpack.guice.ConfigurableModule<SessionCookieConfig>
-
- ratpack.session.SessionModule
-
- All Implemented Interfaces:
com.google.inject.Module
public class SessionModule extends ConfigurableModule<SessionCookieConfig>
Provides support for HTTP sessions.This module provides the general session API (see
Session
), and a defaultSessionStore
implementation that stores session data in local memory.The session store
It is expected that most applications will provide alternative bindings for the
SessionStore
type, overriding the default. This allows arbitrary stores to be used to persist session data.The default, in memory, implementation stores the data in a
Cache
<
AsciiString
,ByteBuf
>
. This cache instance is provided by this module and defaults to storing a maximum of 1000 entries, discarding least recently used. ThememoryStore(java.util.function.Consumer<? super com.google.common.cache.CacheBuilder<io.netty.util.AsciiString, io.netty.buffer.ByteBuf>>)
methods are provided to conveniently construct alternative cache configurations, if necessary.Serialization
Objects must be serialized to be stored in the session. In order to prevent insecure deserialization, types that are to be used in a session must be declared to be safe. The simplest way to do this is to use
allowTypes(com.google.inject.Binder, java.lang.Class<?>...)
to register the type. SeeSessionTypeFilter
for more information. Trying to store or load a type that has not been allowed will result in a runtime exception. Note that all types involved in serializing/deserializing a type must be registered, including super types.The get/set methods
SessionData
allow supplying aSessionSerializer
to be used for the specific value. For variants of the get/set methods where a serializer is not provided, the implementation ofSessionSerializer
bound with Guice will be used. The default implementation provided by this module uses Java's in built serialization mechanism. Users of this module may choose to override this binding with an alternative serialization strategy.However, other Ratpack extensions may require session storage and rely on Java serialization. For this reason, there is also always a
JavaSessionSerializer
implementation available that is guaranteed to be able to serialize anySerializable
object (that conforms to theSerializable
contract. Users of this module may also choose to override this binding with another implementation (e.g. one based on Kryo), but this implementation must be able to serialize any object implementingSerializable
.It is also often desirable to provide alternative implementations for
SessionSerializer
andJavaSessionSerializer
. The default binding for both types is an implementation that uses out-of-the-box Java serialization (which is neither fast nor efficient).Example usage
import ratpack.guice.Guice; import ratpack.core.path.PathTokens; import ratpack.session.Session; import ratpack.session.SessionModule; import ratpack.test.embed.EmbeddedApp; import static org.junit.jupiter.api.Assertions.assertEquals; public class Example { public static void main(String... args) throws Exception { EmbeddedApp.of(a -> a .registry(Guice.registry(b -> b .module(SessionModule.class) )) .handlers(c -> c .get("set/:name/:value", ctx -> ctx.get(Session.class).getData().then(sessionData -> { PathTokens pathTokens = ctx.getPathTokens(); sessionData.set(pathTokens.get("name"), pathTokens.get("value")); ctx.render("ok"); }) ) .get("get/:name", ctx -> { ctx.get(Session.class).getData() .map(d -> d.require(ctx.getPathTokens().get("name"))) .then(ctx::render); }) ) ).test(httpClient -> { assertEquals("ok", httpClient.getText("set/foo/bar")); assertEquals("bar", httpClient.getText("get/foo")); assertEquals("ok", httpClient.getText("set/foo/baz")); assertEquals("baz", httpClient.getText("get/foo")); }); } }
-
-
Field Summary
Fields Modifier and Type Field Description static com.google.inject.Key<com.google.common.cache.Cache<io.netty.util.AsciiString,io.netty.buffer.ByteBuf>>
LOCAL_MEMORY_SESSION_CACHE_BINDING_KEY
The key of the binding for theCache
implementation that backs the in memory session store.static String
LOCAL_MEMORY_SESSION_CACHE_BINDING_NAME
The name of the binding for theCache
implementation that backs the in memory session store.
-
Constructor Summary
Constructors Constructor Description SessionModule()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static void
allowTypes(com.google.inject.Binder binder, Class<?>... types)
Registers the given types as being session safe.static com.google.inject.binder.LinkedBindingBuilder<SessionTypeFilterPlugin>
bindSessionTypeFilterPlugin(com.google.inject.Binder binder)
Creates a multi-binding binder for aSessionTypeFilterPlugin
.protected void
configure()
static void
memoryStore(com.google.inject.Binder binder, Consumer<? super com.google.common.cache.CacheBuilder<io.netty.util.AsciiString,io.netty.buffer.ByteBuf>> config)
A builder for an alternative cache for the default in memory store.static Action<com.google.inject.Binder>
memoryStore(Consumer<? super com.google.common.cache.CacheBuilder<io.netty.util.AsciiString,io.netty.buffer.ByteBuf>> config)
A builder for an alternative cache for the default in memory store.-
Methods inherited from class ratpack.guice.ConfigurableModule
configure, createConfig, defaultConfig, setConfig
-
Methods inherited from class com.google.inject.AbstractModule
addError, addError, addError, bind, bind, bind, bindConstant, binder, bindInterceptor, bindListener, bindListener, bindScope, configure, convertToTypes, currentStage, getMembersInjector, getMembersInjector, getProvider, getProvider, install, requestInjection, requestStaticInjection, requireBinding, requireBinding
-
-
-
-
Field Detail
-
LOCAL_MEMORY_SESSION_CACHE_BINDING_NAME
public static final String LOCAL_MEMORY_SESSION_CACHE_BINDING_NAME
The name of the binding for theCache
implementation that backs the in memory session store.- See Also:
memoryStore(Consumer)
, Constant Field Values
-
LOCAL_MEMORY_SESSION_CACHE_BINDING_KEY
public static final com.google.inject.Key<com.google.common.cache.Cache<io.netty.util.AsciiString,io.netty.buffer.ByteBuf>> LOCAL_MEMORY_SESSION_CACHE_BINDING_KEY
The key of the binding for theCache
implementation that backs the in memory session store.- See Also:
memoryStore(Consumer)
-
-
Method Detail
-
memoryStore
public static Action<com.google.inject.Binder> memoryStore(Consumer<? super com.google.common.cache.CacheBuilder<io.netty.util.AsciiString,io.netty.buffer.ByteBuf>> config)
A builder for an alternative cache for the default in memory store.This method is intended to be used with the
BindingsSpec.binder(Action)
method.import ratpack.guice.Guice; import ratpack.session.SessionModule; public class Example { public static void main(String... args) { Guice.registry(b -> b .binder(SessionModule.memoryStore(c -> c.maximumSize(100))) ); } }
- Parameters:
config
- the cache configuration- Returns:
- an action that binds the cache
- See Also:
memoryStore(Binder, Consumer)
-
memoryStore
public static void memoryStore(com.google.inject.Binder binder, Consumer<? super com.google.common.cache.CacheBuilder<io.netty.util.AsciiString,io.netty.buffer.ByteBuf>> config)
A builder for an alternative cache for the default in memory store.This method can be used from within a custom
Module
.
}import com.google.inject.AbstractModule; import ratpack.session.SessionModule; public class CustomSessionModule extends AbstractModule { protected void configure() { SessionModule.memoryStore(binder(), c -> c.maximumSize(100)); } }
This method binds the built cache with the
LOCAL_MEMORY_SESSION_CACHE_BINDING_KEY
key. It also implicitly registers aRemovalListener
, that releases the byte buffers as they are discarded.- Parameters:
binder
- the guice binderconfig
- the cache configuration
-
allowTypes
public static void allowTypes(com.google.inject.Binder binder, Class<?>... types)
Registers the given types as being session safe.This method is only effectual if the implementation of
SessionTypeFilter
provided by this module is not overridden.import com.google.inject.AbstractModule; import ratpack.session.Session; import ratpack.session.SessionModule; import ratpack.guice.Guice; import ratpack.test.embed.EmbeddedApp; import java.io.Serializable; import static org.junit.jupiter.api.Assertions.assertEquals; public class Example { static class AllowedType implements Serializable { } static class NonAllowedType implements Serializable { } static class NonAllowedTypeContainer implements Serializable { NonAllowedType nonAllowedType = new NonAllowedType(); } public static class MySessionTypesModule extends AbstractModule { protected void configure() { SessionModule.allowTypes(binder(), AllowedType.class, NonAllowedTypeContainer.class ); } } public static void main(String... args) throws Exception { EmbeddedApp.of(a -> a .registry(Guice.registry(b -> b .module(SessionModule.class) .module(MySessionTypesModule.class) )) .handlers(c -> c .get("set/allowed", ctx -> ctx.get(Session.class) .set(new AllowedType()) .then(() -> ctx.render("ok")) ) .get("set/nonAllowed", ctx -> ctx.get(Session.class) .set(new NonAllowedType()) .onError(e -> ctx.render(e.toString())) .then(() -> ctx.render("ok")) ) .get("set/nonAllowedContainer", ctx -> ctx.get(Session.class) .set(new NonAllowedTypeContainer()) .onError(e -> ctx.render(e.toString())) .then(() -> ctx.render("ok")) ) ) ).test(http -> { // Works, only references allowed types String response1 = http.getText("set/allowed"); assertEquals("ok", response1); // Doesn't work, tries to set not allowed type String response2 = http.getText("set/nonAllowed"); assertEquals("ratpack.session.NonAllowedSessionTypeException: Type Example$NonAllowedType is not an allowed session type. Register a SessionTypeFilterPlugin allowing it. See SessionModule.allowTypes().", response2); // Doesn't work, allowed type references not allowed type String response3 = http.getText("set/nonAllowedContainer"); assertEquals("ratpack.session.NonAllowedSessionTypeException: Type Example$NonAllowedType is not an allowed session type. Register a SessionTypeFilterPlugin allowing it. See SessionModule.allowTypes().", response3); }); } }
While the above example only shows type checking being applied on writing to the session, the same checking is applied when reading from the session.
- Parameters:
binder
- the bindertypes
- the types to allow to be used in a session- Since:
- 1.9
-
bindSessionTypeFilterPlugin
public static com.google.inject.binder.LinkedBindingBuilder<SessionTypeFilterPlugin> bindSessionTypeFilterPlugin(com.google.inject.Binder binder)
Creates a multi-binding binder for aSessionTypeFilterPlugin
.- Parameters:
binder
- the binder- Returns:
- a binding builder for a
SessionTypeFilterPlugin
-
configure
protected void configure()
- Overrides:
configure
in classcom.google.inject.AbstractModule
-
-