Метод @PreDestroy не вызывается при выходе со страницы bean-компонента с аннотацией OmniFaces «ViewScoped»

Я пытаюсь вызвать метод, аннотированный @PreDestroy в @ViewScoped bean-компоненте, когда пользователь покидает страницу, связанную с этим bean-компонентом, в довольно большом веб-приложении на основе JSF.

Прочитав https://stackoverflow.com/a/15391453/5467214 и несколько других вопросов и ответов по SO, а также https://showcase.omnifaces.org/cdi/ViewScoped, я пришел к понимая, что аннотация OmniFaces ViewScoped обеспечивает именно такое поведение, используя событие страницы unload, а также sendBeacon в современных браузерах.

Поэтому я использовал аннотацию @ViewScoped из OmniFaces в своем bean-компоненте:

import javax.annotation.PreDestroy;
import org.omnifaces.cdi.ViewScoped;

@Named("DesktopForm")
@ViewScoped
public class DesktopForm implements Serializable {
   ...
}

и аннотировал метод, который я хочу вызвать, аннотацией PreDestroy:

@PreDestroy
public void close() {
    System.out.println("Destroying view scoped desktop bean");
    ...
}

К сожалению, этот метод "закрыть" не вызывается, когда я нажимаю на какую-либо ссылку или покидаю страницу. путем ввода совершенно нового URL. Вместо этого сетевой анализ моего браузера (текущий Firefox) показывает мне, что запрос POST отправляется при выходе со страницы, которая возвращается с кодом ошибки 403 http:

Как вы можете видеть на снимке экрана, «инициатором» POST-запроса является скрипт unload.js.jsf с beacon, упомянутым в скобках, который, как я полагаю, является частью библиотеки OmniFaces. Так что предположительно функционал, описанный в документации OmniFaces ViewScoped, каким-то образом срабатывает, но не приводит к ожидаемому для меня поведению.

Браузер по-прежнему переходит на новую страницу, но аннотированный метод PreDestroy не срабатывает. Когда я переключаюсь на стандартную версию ViewScoped (javax.faces.view.ViewScoped вместо org.omnifaces.cdi.ViewScoped), естественно, метод все еще не вызывается, но также нет метода POST, приводящего к статусу ошибки 403 при выходе со страницы в анализе сети моего браузера ( потому что стандартная ViewScoped аннотация Java не пытается вызвать какое-либо стороннее действие bean-компонента для unload событий, я думаю)

Я использую MyFaces 2.3.10 в сочетании с OmniFaces 2.7.18 (и PrimeFaces 8.0.5, я не знаю, актуально ли это), Spring Security 5.7.3 и Java 11.

Поскольку «403» — это статус http для «запрещено», может ли это иметь какое-то отношение к использованию «http» вместо «https» в моей локальной среде разработки? Этот «отправить маяк» работает только с безопасными соединениями?

Любая помощь приветствуется!

Обновлено: я также ознакомился с официальной документацией аннотации OmniFaces ViewScoped под https://omnifaces.org/docs/javadoc/2.7/index.html?org/omnifaces/cdi/ViewScoped.html, но не смог найти причину для проблемы, с которой я сталкиваюсь.

403 в основном означает, что используемая структура аутентификации не может проверить/авторизовать вошедшего в систему пользователя, связанного с запросом. Попробуйте деактивировать Spring Security (или перенастроить его на «разрешить все») и посмотреть, будет ли он по-прежнему возвращать 403. Если это работает, вам, вероятно, нужно перенастроить Spring Security, чтобы всегда разрешать запросы на выгрузку (см. также «Обнаружение запросов на выгрузку» в документации OmniFaces). ).

BalusC 02.11.2022 17:03

Большое спасибо за помощь, BalusC! Ваш совет помог мне решить мою проблему!

scholt 15.11.2022 15:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С помощью комментария BalusC к моему вопросу выше я смог решить свою проблему. Дело дошло до того, что события unload неправильно обрабатывались нашей цепочкой фильтров. В частности, им было отказано в доступе к методу doFilter расширения нашего класса org.springframework.web.filter.GenericFilterBean.

Поэтому я добавил

if (ViewScopeManager.isUnloadRequest(httpServletRequest)) {
    chain.doFilter(request, response);
}

к методу doFilter упомянутого класса, и тогда это сработало.

Кстати, мне пришлось обновить мою библиотеку OmniFaces с 2.7.18 до 3.13.3, потому что класс ViewScopeManager OmniFaces 2 имеет только один метод isUnloadRequest , который принимает FacesContext в качестве параметра, которого у меня не было в наше расширение GenericFilterBean. С другой стороны, OmniFaces 3.1 предоставляет другой метод с тем же именем, который вместо этого работает с экземпляром HttpServletRequest, к которому у меня был доступ, и поэтому проблема решена.

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