Skip to content

Commit

Permalink
Polish docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Winch committed Jan 6, 2015
1 parent cdf5250 commit 090d106
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 227 deletions.
133 changes: 86 additions & 47 deletions docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ Rob Winch
[[abstract]]

Spring Session provides an API and implementations for managing a user's session information.
It also provides transparent integration with:

* HttpSession - allows for simple clustered sessions,
obtaining the session from custom parts of the HTTP request (i.e. HTTP headers),
and managing multiple user's sessions in a single browser instance (i.e. multiple authenticated accounts similar to Google).
[[introduction]]
== Introduction

* WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages
Spring Session provides an API and implementations for managing a user's session information. It also provides transparent integration with:

* <<httpsession,HttpSession>> - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way.
Additional features include:
** **Clustered Sessions** - Spring Session makes it trivial to support <<httpsession-redis,clustered sessions>> without being tied to an application container specific solution.
** **Multiple Browser Sessions** - Spring Session supports <<httpsession-multi,managing multiple users' sessions>> in a single browser instance (i.e. multiple authenticated accounts similar to Google).
** **RESTful APIs** - Spring Session allows providing session ids in headers to work with <<httpsession-rest,RESTful APIs>>

* <<websocket,WebSocket>> - provides the ability to keep the `HttpSession` alive when receiving WebSocket messages

[[samples]]
= Samples and Guides (Start Here)
== Samples and Guides (Start Here)

If you are looking to get started with Spring Session, the best place to start is our Sample Applications.

Expand All @@ -31,7 +37,7 @@ If you are looking to get started with Spring Session, the best place to start i

| {gh-samples-url}boot[Spring Boot]
| Demonstrates how to use Spring Session with Spring Boot.
| link:guides/boot.html[Spring Boot]
| link:guides/boot.html[Spring Boot Guide]

| {gh-samples-url}security[Spring Security]
| Demonstrates how to use Spring Session with an existing Spring Security application.
Expand All @@ -41,9 +47,9 @@ If you are looking to get started with Spring Session, the best place to start i
| Demonstrates how to use Spring Session in a REST application to support authenticating with a header.
| link:guides/rest.html[REST Guide]

| {gh-samples-url}users[Multiple Sessions]
| {gh-samples-url}users[Multiple Users]
| Demonstrates how to use Spring Session to manage multiple simultaneous browser sessions (i.e Google Accounts).
| link:guides/users.html[Users Guide]
| link:guides/users.html[Manage Multiple Users Guide]

| {gh-samples-url}websocket[WebSocket]
| Demonstrates how to use Spring Session with WebSockets.
Expand All @@ -57,29 +63,39 @@ If you are looking to get started with Spring Session, the best place to start i
|===

[[httpsession]]
= HttpSession Integration
== HttpSession Integration

Spring Session provides transparent integration with `HttpSession`.
This means that developers can switch the `HttpSession` implementation out with an implementation that is backed by Spring Session.

== HttpSession Usage
[[httpsession-why]]
=== Why Spring Session & HttpSession?

We have already mentioned that Spring Session provides transparent integration with `HttpSession`, but what benefits do we get out of this?

* **Clustered Sessions** - Spring Session makes it trivial to support <<httpsession-redis,clustered sessions>> without being tied to an application container specific solution.
* **Multiple Browser Sessions** - Spring Session supports <<httpsession-multi,managing multiple users' sessions>> in a single browser instance (i.e. multiple authenticated accounts similar to Google).
* **RESTful APIs** - Spring Session allows providing session ids in headers to work with <<httpsession-rest,RESTful APIs>>

[[httpsession-redis]]
=== HttpSession with Redis

Using Spring Session with `HttpSession` is enabled by adding a Servlet Filter before anything that uses the `HttpSession`.

The <<samples, HttpSession Sample>> provides a working sample on how to integrate Spring Session and `HttpSession`.
You can the basic steps for integration below, but you are encouraged to follow along with the detailed HttpSession Guide when integrating with your own application:
NOTE: The <<samples, HttpSession Sample>> provides a working sample on how to integrate Spring Session and `HttpSession`.
You can the basic steps for integration below, but you are encouraged to follow along with the detailed HttpSession Guide when integrating with your own application.

include::guides/httpsession.adoc[tags=config,leveloffset=+1]
include::guides/httpsession.adoc[tags=config,leveloffset=+2]

[[httpsession-how]]
== How HttpSession Integration Works
=== How HttpSession Integration Works

Fortunately both `HttpSession` and `HttpServletRequest` (the API for obtaining an `HttpSession`) are both interfaces.
This means that we can provide our own implementations for each of these APIs.

NOTE: This section describes how Spring Session provides transparent integration with `HttpSession`. The intent is so that user's can understand what is happening under the covers. This functionality is already integrated and you do NOT need to implement this logic yourself.

First we create a custom `HttpServletRequest` that returns a custom implementation of `HttpSession'.
First we create a custom `HttpServletRequest` that returns a custom implementation of `HttpSession`.
It looks something like the following:

[source, java]
Expand Down Expand Up @@ -127,30 +143,33 @@ public class SessionRepositoryFilter implements Filter {
By passing in a custom `HttpServletRequest` implementation into the `FilterChain` we ensure that anything invoked after our `Filter` uses the custom `HttpSession` implementation.
This highlights why it is important that Spring Session's `SessionRepositoryFilter` must be placed before anything that interacts with the `HttpSession`.

== Multiple Sessions in Single Browser
[[httpsession-multi]]
=== Multiple HttpSessions in Single Browser

Spring Session has the ability to support multiple sessions in a single browser instance.
This provides the ability to support authenticating with multiple users in the same browser instance (i.e. Google Accounts).

The <<samples,Multiple Sessions Sample>> provides a complete working example of managing multiple users in the same browser instance.
NOTE: The <<samples,Manage Multiple Users Guide>> provides a complete working example of managing multiple users in the same browser instance.
You can the basic steps for integration below, but you are encouraged to follow along with the detailed Manage Multiple Users Guide when integrating with your own application.

include::guides/users.adoc[tags=how-does-it-work]
include::guides/users.adoc[tags=how-does-it-work,leveloffset=+1]

== RESTful APIs
[[httpsession-rest]]
=== HttpSession & RESTful APIs

Spring Session has can work with RESTful APIs by allowing the session to be provided in a header.

The <<samples,REST Sample>> provides a complete working example of using Spring Session with a RESTful API.

[[websocket]]
= WebSocket Integration
== WebSocket Integration

Spring Session provides transparent integration with Spring's WebSocket support.

include::guides/websocket.adoc[tags=disclaimer]
include::guides/websocket.adoc[tags=disclaimer,leveloffset=+1]

[[websocket-why]]
== Why Spring Session & WebSockets?
=== Why Spring Session & WebSockets?

So why do we need Spring Session when using WebSockets?

Expand All @@ -163,23 +182,25 @@ Another issue is that according to JSR-356 if the `HttpSession` times out any We
This means that if we are actively chatting in our application and are not using the HttpSession, then we will also disconnect from our conversation!

[[websocket-usage]]
== WebSocket Usage
=== WebSocket Usage

The <<samples, WebSocket Sample>> provides a working sample on how to integrate Spring Session with WebSockets.
You can the basic steps for integration below, but you are encouraged to follow along with the detailed WebSocket Guide when integrating with your own application:

=== HttpSession Integration
[[websocket-httpsession]]
==== HttpSession Integration

Before using WebSocket integration, you should be sure that you have <<httpsession>> working first.

include::guides/websocket.adoc[tags=config,leveloffset=+1]

include::guides/websocket.adoc[tags=config,leveloffset=+2]

= API Documentation
[[api]]
== API Documentation

You can browse the complete link:../../api/[Javadoc] online. The key APIs are described below:

== Session
[[api-session]]
=== Session

A `Session` is a simplified `Map` of name value pairs.

Expand All @@ -197,7 +218,8 @@ include::{indexdoc-tests}[tags=repository-demo]
<5> We retrieve the `Session` from the `SessionRepository`.
<6> We obtain the persisted `User` from our `Session` without the need for explicitly casting our attribute.

== ExpiringSession
[[api-expiringsession]]
=== ExpiringSession

An `ExpiringSession` extends a `Session` by providing attributes related to the `Session` instance's expiration.
If there is no need to interact with the expiration information, prefer using the more simple `Session` API.
Expand All @@ -221,20 +243,23 @@ The last accessed time is automatically updated when the `ExpiringSession` is sa
<5> We retrieve the `ExpiringSession` from the `SessionRepository`.
If the `ExpiringSession` were expired, the result would be null.

== SessionRepository
[[api-sessionrepository]]
=== SessionRepository

A `SessionRepository` is in charge of creating, retrieving, and persisting `Session` instances.

If possible, developers should not interact directly with a `SessionRepository` or a `Session`.
Instead, developers should prefer interacting with `SessionRepository` and `Session` indirectly through the <<httpsession,HttpSession>> and <<websocket,WebSocket>> integration.

== RedisOperationsSessionRepository
[[api-redisoperationssessionrepository]]
=== RedisOperationsSessionRepository

`RedisOperationsSessionRepository` is a `SessionRepository` that is implemented using Spring Data's `RedisOperations`.
In a web environment, this is typically used in combination with `SessionRepositoryFilter`.
The implementation supports `SessionDestroyedEvent` through `SessionMessageListener`.

=== Instantiating a RedisOperationsSessionRepository
[[api-redisoperationssessionrepository-new]]
==== Instantiating a RedisOperationsSessionRepository

A typical example of how to create a new instance can be seen below:

Expand All @@ -245,7 +270,8 @@ include::{indexdoc-tests}[tags=new-redisoperationssessionrepository]

For additional information on how to create a `RedisConnectionFactory`, refer to the Spring Data Redis Reference.

=== Storage Details
[[api-redisoperationssessionrepository-storage]]
==== Storage Details

Each session is stored in Redis as a Hash.
Each session is set and updated using the HMSET command.
Expand All @@ -255,7 +281,8 @@ An example of how each session is stored can be seen below.
maxInactiveInterval 1800 lastAccessedTime 1404360000000 \
sessionAttr:<attrName> someAttrValue sessionAttr:<attrName2> someAttrValue2

==== Session Expiration
[[api-redisoperationssessionrepository-expiration]]
===== Session Expiration

An expiration is associated to each session using the EXPIRE command based upon the RedisOperationsSessionRepository.RedisSession.getMaxInactiveInterval().
For example:
Expand All @@ -271,7 +298,8 @@ For example:

The Redis expiration is still placed on each key to ensure that if the server is down when the session expires, it is still cleaned up.

==== Optimized Writes
[[api-redisoperationssessionrepository-writes]]
===== Optimized Writes

The `Session` instances managed by `RedisOperationsSessionRepository` keeps track of the properties that have changed and only updates those.
This means if an attribute is written once and read many times we only need to write that attribute once.
Expand All @@ -281,7 +309,8 @@ The following would be executed upon saving:
HMSET spring:session:sessions:<session-id> sessionAttr:<attrName2> newValue
EXPIRE spring:session:sessions:<session-id> 1800

=== SessionDestroyedEvent
[[api-redisoperationssessionrepository-sessiondestroyedevent]]
==== SessionDestroyedEvent

`RedisOperationsSessionRepository` supports firing a `SessionDestroyedEvent` whenever a `Session` is deleted or when it expires.
This is necessary to ensure resources associated with the `Session` are properly cleaned up.
Expand All @@ -298,7 +327,8 @@ TIP: If you are using `@EnableRedisHttpSession` the `SessionMessageListener` and
redis-cli config set notify-keyspace-events Egx
----

=== Viewing the Session in Redis
[[api-redisoperationssessionrepository-cli]]
==== Viewing the Session in Redis

After http://redis.io/topics/quickstart[installing redis-cli], you can inspect the values in Redis http://redis.io/commands#hash[using the redis-cli].
For example, enter the following into a terminal:
Expand Down Expand Up @@ -327,13 +357,15 @@ redis 127.0.0.1:6379> hget spring:session:sessions:4fc39ce3-63b3-4e17-b1c4-5e1ed
"\xac\xed\x00\x05t\x00\x03rob"
----

== MapSessionRepository
[[api-mapsessionrepository]]
=== MapSessionRepository

The `MapSessionRepository` allows for persisting `ExpiringSession` in a `Map` with the key being the `ExpiringSession` id and the value being the `ExpiringSession`.
The implementation can be used with a `ConcurrentHashMap` as a testing or convenience mechanism.
Alternatively, it can be used with distributed `Map` implementations. For example, it can be used with Hazelcast.

=== Instantiating MapSessionRepository
[[api-mapsessionrepository-new]]
==== Instantiating MapSessionRepository

Creating a new instance is as simple as:

Expand All @@ -342,35 +374,42 @@ Creating a new instance is as simple as:
include::{indexdoc-tests}[tags=new-mapsessionrepository]
----

=== Using Spring Session and Hazlecast
[[api-mapsessionrepository-hazelcast]]
==== Using Spring Session and Hazlecast

The <<samples,Hazelcast Sample>> is a complete application demonstrating using Spring Session with Hazelcast.
To run it use the following:

./gradlew :samples:hazelcast:tomcatRun

= Spring Session Community
[[community]]
== Spring Session Community

We are glad to consider you a part of our community.
Please find additional information below.

== Support
[[community-support]]
=== Support

You can get help by asking questions on http://stackoverflow.com/questions/tagged/spring-session[StackOverflow with the tag spring-session].
Similarly we encourage helping others by answering questions on StackOverflow.

== Source Code
[[community-source]]
=== Source Code

Our source code can be found on github at https://github.com/spring-projects/spring-session/

== Issue Tracking
[[community-issues]]
=== Issue Tracking

We track issues in github issues at https://github.com/spring-projects/spring-session/issues

== Contributing
[[community-contributing]]
=== Contributing

We appreciate https://help.github.com/articles/using-pull-requests/[Pull Requests].

== License
[[community-license]]
=== License

Spring Session is Open Source software released under the http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].
18 changes: 0 additions & 18 deletions samples/boot/src/main/java/sample/config/HttpSessionConfig.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package sample.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
* @author Rob Winch
*/
@Configuration
@EnableRedisHttpSession // <1>
public class HttpSessionConfig {
Expand Down
18 changes: 0 additions & 18 deletions samples/httpsession/src/main/java/sample/Config.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package sample;

import org.springframework.context.annotation.Bean;
Expand All @@ -21,9 +6,6 @@
import org.springframework.data.redis.connection.jedis.*;
import org.springframework.session.data.redis.config.annotation.web.http.*;

/**
* @author Rob Winch
*/
@Import(EmbeddedRedisConfiguration.class) // <1>
@EnableRedisHttpSession // <2>
public class Config {
Expand Down
Loading

0 comments on commit 090d106

Please sign in to comment.