Бин ViewScoped создается по каждому запросу... часть 99
ARGH... Кажется, у этого есть сто ответов, и я не нашел тот, который подходит для меня, поэтому я думаю, что на самом деле спросить его снова. Вот мой сценарий:
Технически мой сайт имеет одну страницу, содержимое которой заменяется, а не несколько страниц, на которые вы переходите. Отправной точкой является этот кусок:
<?xml version="1.0" encoding="UTF-8"?>
<f:view xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />
<h:body>
<ui:include src="resourceInclude.xhtml" />
<ui:include src="main.xhtml" />
</h:body>
</f:view>
ResourceInclude.xhtml включает мой файл css:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:outputStylesheet library="css" name="test.css" target="head" />
</ui:composition>
И main.xhtml это представление:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:panelGroup styleClass="test-container" layout="block">
<h:form id="main-form">
<h:panelGroup styleClass="test-header" layout="block">
<h:panelGroup styleClass="navigation" layout="block">
<ul>
<li><h:commandLink action="#{viewSelector.setModeHome}">
<h:outputText value="Home" />
</h:commandLink></li>
<li><h:commandLink action="#{viewSelector.setModeReports}">
<h:outputText value="ASAP Reports" />
</h:commandLink></li>
<li><h:commandLink action="#{viewSelector.setModeSupport}">
<h:outputText value="Technical Support" />
</h:commandLink></li>
<li><h:commandLink action="#{viewSelector.setModeHelp}">
<h:outputText value="Help" />
</h:commandLink></li>
</ul>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup styleClass="test-content" layout="block">
<ui:include src="#{viewSelector.modeName}-view.xhtml" />
</h:panelGroup>
<h:panelGroup styleClass="test-footer" layout="block">
<h:messages />
</h:panelGroup>
</h:form>
</h:panelGroup>
</ui:composition>
Состоит из трех h:panelGroup
s. Первая представляет собой набор из четырех общих навигационных ссылок, каждая из которых изменяет viewSelector.modeName
значение, которое используется для включения содержимого во втором h:panelGroup
константы выглядит <ui:include src="#{viewSelector.modeName}-view.xhtml" />
, Я сократил это для этого примера, поэтому каждое представление в основном таково:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:panelGroup styleClass="test-home-view">
<p>home</p>
</h:panelGroup>
</ui:composition>
Третий h:panelGroup
нижний колонтитул для всех сообщений для отладки того, что идет не так.
В любом случае, каждый раз, когда я нажимаю одну из навигационных ссылок, вызывается конструктор bean-компонента viewSelector. Вот как выглядит мой bean-компонент viewSelector:
package org.mitre.asias.aires.controller;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.apache.log4j.Logger;
@ManagedBean( name="viewSelector" )
@ViewScoped
public class ViewSelector {
protected static Logger log = Logger.getLogger( ViewSelector.class );
private Mode mode = Mode.HOME;
public static final String PORTLET_NAME = "Test";
public static enum Mode {
HOME(1, "home"),
REPORTS(2, "reports"),
SUPPORT(3, "support"),
HELP(4, "help");
private int value;
private String name;
private Mode( int value, String name ) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}
public ViewSelector() {
log.trace( "constructing new ViewSelector" );
}
public Mode getMode() {
log.trace( "getting mode" );
return mode;
}
public String getModeName() {
log.debug( "in getmodename" );
return getMode().getName();
}
public String getPortletName() {
return PORTLET_NAME;
}
public boolean isModeReports() {
return getMode() == Mode.REPORTS;
}
public void setMode( Mode mode ) {
this.mode = mode;
}
public void setModeHelp() {
setMode( Mode.HELP );
}
public void setModeHome() {
setMode( mode = Mode.HOME );
}
public void setModeReports() {
setMode( mode = Mode.REPORTS );
}
public void setModeSupport() {
setMode( mode = Mode.SUPPORT );
}
}
Я знаю, что, должно быть, что-то делаю не так, иначе мне не хватало чего-то важного в том, как работает JSF. Любой вход?
1 ответ
EL в <ui:include src>
вызывает это.
Если отключить сохранение частичного состояния в web.xml
согласно вопросу 1492 не вариант,
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>true</param-value>
</context-param>
тогда вам нужно заменить
<ui:include src="#{viewSelector.modeName}-view.xhtml" />
чем-то вроде
<h:panelGroup rendered="#{viewSelector.mode == 'HOME'}">
<ui:include src="home-view.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{viewSelector.mode == 'REPORTS'}">
<ui:include src="reports-view.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{viewSelector.mode == 'SUPPORT'}">
<ui:include src="support-view.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{viewSelector.mode == 'HELP'}">
<ui:include src="help-view.xhtml" />
</h:panelGroup>
Подобный вопрос был задан хотя бы один раз ранее:)