Управление данными сеанса webapp / потоком контроллера для нескольких вкладок

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

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

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

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

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

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

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

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

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

4 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам