2015-03-24 1 views
0

Вот мой вопрос: я пишу платформу, которую я дам клиентам для реализации своих проектов. Так что в моей платформе я создал 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 с моих контроллеров, на мои фасады, на сервисный уровень, который находится очень близко к слою db. Это выглядит очень плохой идеей для меня, поэтому мой вопрос: есть ли способ получить currentSession около уровня db? Один из способов, я думаю, - написать перехватчик, который будет вызываться контроллерами, которые будут устанавливать текущий сеанс в репозитории или услугу. Я просто не уверен, что это правильный путь.

ответ

1

Получение идентификатор сеанса из Service Layer

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

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

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

Должен ли я помещать это в сессию?

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

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

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

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

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

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