Управление данными сеанса webapp / потоком контроллера для нескольких вкладок - PullRequest
22 голосов
/ 18 декабря 2010

У меня есть веб-приложение на Java, которое хранит некоторые данные в сеансе. Данные в сеансе изменяются, когда пользователь взаимодействует с приложением (например, поток управляется контроллером, каждый контроллер имеет несколько страниц формы, на каждой странице формы некоторые данные обновляются в сеансе, и поток переходит на следующую страницу формы).

Проблема в том, что некоторые пользователи открывают более одной вкладки для приложения, каждая вкладка со своим шагом в процессе. На этом этапе данные в сеансе перепутаны, поскольку вкладки используют один и тот же сеанс (приложение использует сеансы, управляемые cookie).

Указывать пользователям использовать разные браузеры, чтобы они не разделяли один и тот же идентификатор сеанса (например, одно окно Firefox и одно окно IE), не вариант, так как наверняка в какой-то момент кто-то забудет это сделать и вместо этого использовать вкладки, что приведет к путанице их данные.

Добавление некоторых проверок, которые обнаруживают, что другой поток запрашивается из другой вкладки, и отображают сообщение для пользователя, говорящее, что это запрещено, тоже не вариант, так как это раздражает пользователей, и мы не хотим, чтобы мы это делали? : D

Дело в том, что использование другой вкладки полезно для пользователей, поскольку они более эффективны в том, для чего они используют приложение, поэтому я сохраняю эту опцию. Но теперь возникает вопрос: как лучше управлять данными одного сеанса для большего количества вкладок?

Я думал о том, чтобы контроллер генерировал токен при запуске потока и передавал этот токен каждой странице формы, которая, в свою очередь, отправляла его обратно для идентификации себя. Если другая вкладка запрашивает то же действие контроллера при наличии текущего потока, тогда сгенерируйте другой токен и передайте его.

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

Теперь проблема в том, что для этого подхода потребуется много переписать приложение, и мне было интересно, есть ли лучшая практика для управления такой ситуацией или кто-то может предложить другие подходы. Я открыт для идей.

Сталкивались ли вы с этой ситуацией? Как ты справился с этим?

Ответы [ 4 ]

14 голосов
/ 19 декабря 2010

Обычно это делается путем назначения windowId для каждой вкладки / окна и передачи его при каждом запросе. Jsf поддерживает это через orchestra . Spring mvc поддержит его в следующей версии.

Мне недавно понадобилось это для простого случая, поэтому я реализовал это сам. Прошло полчаса. Однако мой кругозор был очень ограничен:

  • передать windowId с каждым запросом и вернуть его для следующего запроса. Первый раз - сгенерируйте его.
  • для любого атрибута, который вы хотите сохранить в сеансе, поместите Map<String, Object>, где ключом является windowId
0 голосов
/ 02 марта 2011

Вы также можете попробовать обернуть ваше приложение внутри Adobe Air

А затем ограничьте доступ к вашему веб-приложению только из этого эфира. При этом вам не нужно учитывать фрагментацию веб-браузера и их уникальное поведение.

0 голосов
/ 02 марта 2011

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

Конечно, это потенциально может повлечь за собой большие начальные затраты, в зависимости от структуры вашего приложения. Без дополнительной информации о вашем приложении вы будете лучшим выбором.

0 голосов
/ 01 марта 2011

Это именно то, что Шов было создано для обработки.В Seam есть концепция под названием Conversation , которая в основном делает именно то, что вы объясняете.Беседы - это способ разделить сессию на множество частей, срок действия которых может истечь через некоторое время.Вы можете посмотреть исходный код класса org.jboss.seam.core.Manager, чтобы увидеть, как он на самом деле реализован и вдохновлен;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...