1. Обзор
В этом кратком руководстве мы рассмотрим, как использовать весеннюю сессию с поддержкой MongoDB , как с загрузкой Spring, так и без нее.
Весенняя сессия также может быть поддержана другими магазинами, такими как Redis и JDBC .
2. Конфигурация пружинной Загрузки
Во-первых, давайте рассмотрим зависимости и конфигурацию, необходимые для загрузки Spring. Для начала давайте добавим в наш проект последние версии spring-session-data-mongodb и spring-boot-starter-data-mongodb :
org.springframework.session spring-session-data-mongodb 2.2.6.RELEASE org.springframework.boot spring-boot-starter-data-mongodb 2.2.6.RELEASE
После этого, чтобы включить автоматическую настройку Spring Boot, нам нужно будет добавить тип хранилища Spring Session как mongodb в application.properties :
spring.session.store-type=mongodb
3. Конфигурация Пружины Без Пружинной Загрузки
Теперь давайте рассмотрим зависимости и конфигурацию, необходимые для хранения весеннего сеанса в MongoDB без загрузки Spring.
Аналогично конфигурации загрузки Spring, нам понадобится зависимость spring-session-data-mongodb . Однако здесь мы будем использовать зависимость spring-data-mongodb для доступа к нашей базе данных MongoDB:
org.springframework.session spring-session-data-mongodb 2.2.6.RELEASE org.springframework.data spring-data-mongodb 2.2.6.RELEASE
Наконец, давайте посмотрим, как настроить приложение:
@EnableMongoHttpSession
public class HttpSessionConfig {
@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
return new JdkMongoSessionConverter(Duration.ofMinutes(30));
}
}Аннотация @ Enable Mongo HttpSession включает конфигурацию, необходимую для хранения данных сеанса в MongoDB .
Кроме того, обратите внимание, что JdkMongoSessionConverter отвечает за сериализацию и десериализацию данных сеанса.
4. Пример применения
Давайте создадим приложение для тестирования конфигураций. Мы будем использовать Spring Boot, так как он быстрее и требует меньше настроек.
Мы начнем с создания контроллера для обработки запросов:
@RestController
public class SpringSessionMongoDBController {
@GetMapping("/")
public ResponseEntity count(HttpSession session) {
Integer counter = (Integer) session.getAttribute("count");
if (counter == null) {
counter = 1;
} else {
counter++;
}
session.setAttribute("count", counter);
return ResponseEntity.ok(counter);
}
} Как мы можем видеть в этом примере, мы увеличиваем счетчик при каждом попадании в конечную точку и сохраняем его значение в атрибуте сеанса с именем count .
5. Тестирование приложения
Давайте протестируем приложение, чтобы увидеть, действительно ли мы можем хранить данные сеанса в MongoDB.
Для этого мы получим доступ к конечной точке и проверим файл cookie, который мы получим. Это будет содержать идентификатор сеанса.
После этого мы запросим коллекцию MongoDB, чтобы получить данные сеанса, используя идентификатор сеанса:
@Test
public void
givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() {
HttpEntity response = restTemplate
.exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class);
HttpHeaders headers = response.getHeaders();
String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE);
Assert.assertEquals(response.getBody(),
repository.findById(getSessionId(set_cookie)).getAttribute("count").toString());
}
private String getSessionId(String cookie) {
return new String(Base64.getDecoder().decode(cookie.split(";")[0].split("=")[1]));
} 6. Как Это Работает?
Давайте посмотрим, что происходит за кулисами весенней сессии.
SessionRepositoryFilter отвечает за большую часть работы:
- преобразует HttpSession в MongoSession
- проверяет, присутствует ли файл Cookie , и если да, загружает данные сеанса из хранилища
- сохраняет обновленные данные сеанса в хранилище
- проверяет действительность сеанса
Кроме того, SessionRepositoryFilter создает файл cookie с именем SESSION , который является HttpOnly и безопасным. Этот файл cookie содержит идентификатор сеанса, который является значением в кодировке Base64.
Чтобы настроить имя или свойства файла cookie, нам нужно будет создать компонент Spring типа Сериализатор файлов cookie по умолчанию.
Например, здесь мы отключаем свойство httponly файла cookie:
@Bean
public DefaultCookieSerializer customCookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setUseHttpOnlyCookie(false);
return cookieSerializer;
}7. Сведения о сеансе, хранящиеся в MongoDB
Давайте запросим нашу коллекцию сеансов, используя следующую команду в нашей консоли MongoDB:
db.sessions.findOne()
В результате мы получим документ BSON, аналогичный:
{
"_id" : "5d985be4-217c-472c-ae02-d6fca454662b",
"created" : ISODate("2019-05-14T16:45:41.021Z"),
"accessed" : ISODate("2019-05-14T17:18:59.118Z"),
"interval" : "PT30M",
"principal" : null,
"expireAt" : ISODate("2019-05-14T17:48:59.118Z"),
"attr" : BinData(0,"rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAFY291bnRzcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAC3g=")
}_id – это UUID , который будет закодирован в Base64 с помощью файла cookie по умолчанию, сериализованного и отправленного в качестве значения в СЕАНСЕ файле cookie. Кроме того, обратите внимание, что атрибут attr содержит фактическое значение нашего счетчика.
8. Заключение
В этом уроке мы изучили весеннюю сессию, поддержанную MongoDB — мощным инструментом для управления HTTP-сессиями в распределенной системе. С учетом этой цели он может быть очень полезен при решении проблемы репликации сеансов в нескольких экземплярах приложения.
Как обычно, исходный код доступен на GitHub .