我们正在迁移JSF 2.1应用程序,从JBoss AS 7.2到Wildfly以及JSF 2.2。我们遇到的问题如下:我们有一个包含在@ViewScoped
bean中的复合组件。组件必须通过多个请求保留其值,因此Request Scoped bean不是解决方案。
我们获得的例外是多组件ID。在请求之后,JSF开始第二次呈现组件,并且失败。
我为此做了一个简单的演示:
MyViewBean.java
@ViewScoped
@Named
public class MyViewBean implements Serializable {
private Component component;
public Component getComponent() {
return component;
}
public void setComponent(Component component) {
this.component = component;
}
public String increment(){
component.setCounter(component.getCounter()+1);
return "";
}
}
Component.java
@FacesComponent(value = "composite")
public class Component extends UINamingContainer {
private Integer counter = 0;
public Integer getCounter() {
return counter;
}
public void setCounter(Integer counter) {
this.counter = counter;
}
}
compositeTest.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
template="/WEB-INF/templates/default.xhtml"
xmlns:pelda="http://xmlns.jcp.org/jsf/composite/component">
<ui:define name="content">
<h1>Composite component Test!</h1>
<h:form>
<pelda:composite binding="#{myViewBean.component}" />
<h:commandButton action="#{myViewBean.increment()}" value="Push me!"/>
</h:form>
</ui:define>
</ui:composition>
composite.xhtml
<cc:interface componentType="composite">
</cc:interface>
<cc:implementation>
<h:outputText id="id_hello" value="Helloka" />
<h:outputText id="id_counter" value="#{cc.counter}" />
</cc:implementation>
</html>
如何实现计数器可以递增(使用@RequestScoped bean重置)并且因为idUniqueness错误而失败?我们正在使用Mojarra 2.2.8(Wildfly中的默认值),也尝试使用Mojarra 2.2.12(最新编写此内容)。
提前致谢!
答案 0 :(得分:2)
UIComponent
个实例本身就是请求作用域。您应该永远引用请求范围之外的UIComponent
个实例。请仔细阅读How does the 'binding' attribute work in JSF? When and how should it be used?以获得详尽的解释。
您只想通过继承的getStateHelper()
方法将其状态保存在JSF状态中。这基本上作为视图范围。
@FacesComponent(value = "composite")
public class Component extends UINamingContainer {
public Integer getCounter() {
return (Integer) getStateHelper().eval("counter", 0);
}
public void setCounter(Integer counter) {
getStateHelper().put("counter", counter);
}
}
请勿忘记删除视图中的binding
属性。