Получить текущую сессию с весенней сессией

Вот мой вопрос: я пишу платформу, которую буду давать клиентам для реализации своих проектов. Итак, на моей платформе я создал SessionService, в котором у меня есть такие методы, как getCurrentSession, getAttribute, setAttribute и т. д. До весенней сессии мой getCurrentMethod выглядел так:

@Override public HttpSession getCurrentSession() { if (this.session == null) { final ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); return attr.getRequest().getSession(true); // true == allow create } return this.session; }

который отлично работал, хотя выглядит уродливо и не имеет такой поддержки, как Redis. Теперь я хочу перейти на spring-session, и я надеялся использовать SessionRepository, чтобы найти текущий сеанс пользователя, однако я вижу там только getSession(String id). Я считаю, что идентификатор хранится в файле cookie, поэтому, чтобы использовать его, мне, вероятно, придется передать объект HttpServletRequest из моих контроллеров на мои фасады на уровень обслуживания, который находится очень близко к уровню базы данных. Мне это кажется очень плохой идеей, поэтому мой вопрос будет таким: есть ли способ получить currentSession рядом с уровнем db? Я думаю, что один из способов — написать перехватчик, который будет вызывать контроллеры, которые будут устанавливать текущий сеанс в репозитории или, может быть, службу? Я просто не уверен, что это правильный путь.


person Petar Tahchiev    schedule 24.03.2015    source источник


Ответы (1)


Получение идентификатора сеанса из сервисного уровня

Вы можете использовать RequestContextHolder для получения идентификатора сеанса, установки атрибутов и удаления атрибутов.

RequestContextHolder обычно настраивается с помощью RequestContextListener или RequestContextFilter. Spring Session НЕ работает с RequestContextListener, потому что Spring Session не может обернуть запрос до того, как будет вызван RequestContextListener.

К сожалению, это означает, что для приложений Spring Boot RequestContextHolder не работает из коробки. Чтобы обойти это, вы можете создать RequestContextFilter Bean. См. spring-boot/gh-2637 для получения обновлений по этому вопросу.

Должен ли я включить это в сеанс?

Просто потому, что в сеанс легко поместить множество объектов, и они хранятся в Redis, это не значит, что это правильно.

Имейте в виду, что весь сеанс извлекается при каждом запросе. Таким образом, хотя Redis работает быстро, это может оказать существенное влияние, если в сеансе много объектов. Очевидно, что реализация может быть оптимизирована для вашей ситуации, но я думаю, что концепция сеанса обычно обладает этим свойством.

Общее эмпирическое правило: «Нужен ли мне этот объект для более чем 95% моих запросов?» (читай так почти все мои просьбы). Если да, то он может быть кандидатом на сеанс. В большинстве случаев объект должен быть связан с безопасностью, если он соответствует этому критерию.

Должен ли я получить доступ к идентификатору сеанса из ThreadLocal на уровне службы?

Это, безусловно, открыто для обсуждения, поскольку программирование — это не только наука, но и искусство.

Однако я бы сказал, что вы не должны получать идентификатор сеанса из переменных локали потока во всей вашей архитектуре. Это похоже на получение «идентификатора человека» и получение текущего «идентификатора человека» из HttpServletRequest в ThreadLocale. Вместо этого значения должны быть получены от контроллера и переданы на уровень вашего сервиса.

person Rob Winch    schedule 31.03.2015