Vaadin 14 addDestroyListener для сеанса, отличного от int SessionDestroyListener

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

      ui.getSession().getService().addSessionDestroyListener( evt -> {
                list.remove(this);
            });

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

Я использую Ваадин 14.8.14.

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

2 ответа

Вы можете выполнять действия для каждого сеанса с помощьюVaadinService::addSessionDestroyListenerпутем добавления фактического прослушивателя только один раз (например, вVaadinServiceInitListenerи сохранение фактического действия в качестве атрибута в каждом сеансе.

Для конкретного примера, который вы показываете, вы можете сохранить элемент списка для удаления в каждом сеансе:

      someSession.setAttribute("item-to-remove", someItem);

И тогда прослушиватель singleton может сделать что-то вроде этого:

      Object itemToRemove = event.getSession().getAttribute("item-to-remove");
list.remove(itemToRemove);

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

Следует отметить одну несвязанную вещь: несколько событий уничтожения сеанса могут запускаться одновременно, что означает, что вам необходимо защитить свой список от одновременной модификации, например, с помощьюCopyOnWriteArrayListили используяCollections::synchronizedList.

Я заставил его работать с сопоставлением VaadinSession с SpringVaadinSession, а затем с помощью addDestroyLsitener:

      VaadinSession session = SpringVaadinSession.getCurrent();
if(session instanceof SpringVaadinSession) {
    ((SpringVaadinSession) session).addDestroyListener(evt -> {
            someFunctionThatIsfiredWhenSessionIsDestoryed();
    });
}

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

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