Как (и когда?) Удалить область сеанса bean в JSF 2.0
Фон: у меня есть приложение JSF 2.0 с использованием MyFaces. Используя это приложение, пользователи создадут сложный "Виджет", пройдя через несколько разных страниц JSF. Я храню управляемый bean в области сеанса, и свойства заполняются, когда пользователь просматривает каждую страницу. После того, как они будут собраны "виджет", они захотят создать новый "виджет" и повторить этот процесс. Мой вопрос: как полностью (и безопасно) удалить управляемый bean из сеанса без нарушения жизненного цикла JSF?
Я видел другие ответы на подобные вопросы, предлагая вам аннулировать сеанс, а также вы можете получить доступ к HttpSession через FacesContext и удалить bean таким образом. Я не хочу, чтобы пользователь должен был выйти из системы или снова, и я не хочу отменять весь сеанс. Предполагая, что мне нужно пройти через FacesContext, чтобы получить доступ к HttpSession и удалить bean, когда в JSF lifecyle является наиболее подходящим местом, чтобы сделать это безопасно, чтобы проблемы не каскадировались через оставшуюся часть цикла? Я хочу убедиться, что у JSF не возникнет проблем с созданием нового сеанса bean, когда пользователь начнет процесс создания следующего "виджета".
Мне также интересно узнать, почему в JSF нет механизма, чтобы сделать это проще. Есть ли какой-то другой подход, который я должен принимать, который лучше соответствует намеченному шаблону JSF? Я не могу использовать View Scope здесь, потому что управляемый bean будет проходить через несколько разных страниц и представлений до его завершения.
Спасибо в Advance!
Ответы
Ответ 1
Создайте одну страницу, в которой вы выполняете несколько шагов мастера.
<h:panelGroup rendered="#{wizard.step == 1}">
<ui:include src="/WEB-INF/wizard/step1.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{wizard.step == 2}">
<ui:include src="/WEB-INF/wizard/step2.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{wizard.step == 3}">
<ui:include src="/WEB-INF/wizard/step3.xhtml" />
</h:panelGroup>
Таким образом, вы можете просто использовать @ViewScoped
управляемый bean на этой странице без особых проблем.
Не привязанный к конкретному вопросу, PrimeFaces имеет <p:wizard>
, что почти так. Вы можете найти это полезным для того, чтобы спасти себя от какого-то болезненного кода шаблона, который касается валидации и т.д.
Ответ 2
Ваш случай может быть упрощен, если данные создания виджета инкапсулированы в один bean.
Я имею в виду
@SessionScoped
@ManagedBean
public class WidgetMaker {
private Widget widget;
public void makeWidget(){
//after creating/saving widget
widget = new Widget();
}
public void resetWidget(){
//this method can be called with pre render view handler
//call this method on the first page that starts widget creation
//in case person leaves the widget creation in between and starts over again
widget = new Widget();
}
}
Для просмотра resetWidget (только на первой странице создания виджета)
<f:metadata>
<f:event type="preRenderView" listener="#{widgetMaker.resetWidget}"/>
</f:metadata>
Вы можете принимать указатели и соответственно адаптироваться.
Надеюсь, что это поможет.
Ответ 3
Хотя я еще не использовал его сам, я бы посмотрел на CDI ConversationScope
.
Ответ 4
Я согласен с BalusC в том, что область обзора будет лучшим выбором в вашем случае. Я просто посмотрел на мой (очень старый) первый проект JSF, где у меня была многостраничная форма в области сеанса. Позже я перешел в режим просмотра по известным причинам.
Однако, я сделал reset сеансовую область bean, просто заменив экземпляр на карте сеанса:
MyBean newInstance = new MyBean();
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().put(beanName, newInstance);
с beanName
как имя bean el (строка).