Мой проект использует JSF2.0 и CDI. Для одной страницы я хочу, чтобы мой поддерживающий компонент соответствовал продолжительности жизни страницы. @ViewScoped кажется идеально подходящим, но он не является частью CDI, а затем делает наше решение несовместимым. Тогда моим следующим вариантом будет CDI @ConversationScoped. Кажется, единственный способ отметить границу разговора - это программный путь через chat.begin и chat.end (я использовал Seam 2.x, там вы можете использовать аннотации для отметки границы разговора). Моя страница сидит в общем макете с глобальной навигацией, что означает, что есть «неограниченные» способы оставить мою страницу. Как я могу убедиться, что разговор завершен в зависимости от того, какой пользователь может выбрать (например, нажав на глобальную навигационную опцию, которая полностью находится за пределами моего бэк-контроля)? И я надеюсь, что решение не распространит код на другие модули; и если это неизбежно, я надеюсь, что это может быть реализовано сквозным образом (АОП).Как очистить CDI @ConversationScoped
ответ
Этого можно достичь с помощью заказа ConfigurableNavigationHandler
.
Реализация JSF NavigationHandler
public class NavigationHandlerTest extends ConfigurableNavigationHandler { private NavigationHandlerTest concreteHandler; public NavigationHandlerTest(NavigationHandler concreteHandler) { this.concreteHandler = concreteHandler; } @Override public void handleNavigation(FacesContext context, String fromAction, String outcome) { //here, check where navigation is coming from and based on that, retrieve the CDI bean and kill the conversation if(fromAction.equals("someAction"){ BeanManager theBeanManager = getBeanManager(context); Bean bean = theBeanManager.getBeans("yourCDIBean").iterator().next() CreationalContext ctx = theBeanManager.createCreationalContext(bean); MyBeanType o = theBeanManager.getReference(bean, bean.getClass(), ctx); //retrieve the bean from the manager by name. You're guaranteed to retrieve only one of the same name; o.getConversation.end(); //end the conversation from the bean reference } //proceed with normal navigation concreteHandler.handleNavigation(context, fromAction, outcome); } //This method provides access to the cdi bean manager. You need it to be able to //gain access to the cdi bean and from that to the injected conversation instance public BeanManager getBeanManager(FacesContext facesContext){ BeanManager cdiBeanManager = (BeanManager)((ServletContext) facesContext.getExternalContext().getContext()).getAttribute("javax.enterprise.inject.spi.BeanManager"); return cdiBeanManager; } }
Зарегистрируйте свой собственный навигационный обработчик в лица-config.xml
<application> <navigation-handler>com.foo.bar.NavigationHandlerTest</navigation-handler> </application>
Этот подход является централизованной и минимально инвазивной
Как я знаю - вы не можете. Практически невозможно (трудно) определить, была ли ссылка открыта на текущей или новой вкладке (для нового вам нужно оставить активную беседу) в JSF.
Но хорошие новости - разговор будет закрыт автоматически через 10 минут бездействия (по умолчанию).
Ну, оставляя проблему дизайна в стороне. Технически вы можете сделать все навигационные запросы через объект службы навигации. И каждый разговор имеет идентификатор. После того, как целевая страница будет открыта, мы сможем сохранить идентификатор в объекте службы, если какой-либо следующий запрос навигации не предназначен для целевой страницы, тогда мы знаем, что нам нужно завершить разговор. Поскольку CDI несколько основан на Seam, я надеялся, что у меня будет более элегантное решение. – chaoshangfei
Обработчик окон на стороне клиента из CODI может правильно определить новую вкладку/окно. –
- 1. CDI @ConversationScoped и JSP
- 2. Разница между JSF FlowScoped и CDI ConversationScoped
- 3. Страницы AJAX с CDI beans и @ConversationScoped
- 4. Использование CDI ConversationScoped beans в контроллерах весны
- 5. Как мне получить компонент ConversationScoped CDI изнутри фильтра?
- 6. Нужен ли мне @LocalBean для @ConversationScoped?
- 7. CDI (Weld) + DeltaSpike + Converstation
- 8. Ошибка CDI EntityManager
- 9. Weld + JSF 2.0 @ConversationScoped не поддерживает состояние
- 10. Как очистить результаты запроса EclipseLink Cache от перехватчика CDI?
- 11. Как использовать ConversationScoped EntityManager внутри StatelessBean
- 12. Как использовать @ConversationScoped с запросами Ajax?
- 13. Java CDI ConversationScope, вызывая таймер?
- 14. CDI Разговор без окончания
- 15. Настройка тайм-аута тайм-аута CDI глобально
- 16. Как использовать беседу в компоненте CDI?
- 17. новый диалог CDI
- 18. Использование транзакции с CDI Разговор
- 19. Howto Let Primefaces работает с @ConversationScoped Beans?
- 20. Ошибка развертывания CDI: WELD-001408 при использовании CDI beans (Glassfish 4.1)
- 21. Могу ли я помещать @ManagedBean в область CDI?
- 22. CDI как завод?
- 23. CDI Injection Within A Constructor
- 24. @ConversationScoped bean ведет себя как @RequestScoped с OmniFaces 2.5 FacesViews
- 25. CDI TransactionInterceptor
- 26. CDI многопоточность
- 27. CDI + Совместимость
- 28. CDI @ApplicationScoped
- 29. Hibernate - CDI
- 30. Как создать валидатор с CDI
Это работает. Благодаря! – chaoshangfei
@FangZhang вас очень приветствует – kolossus
Это уродливое обходное решение. Вместо этого я бы использовал CODI-Conversations. –