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 ResponseEntitycount(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() { HttpEntityresponse = 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 .