情况是我有一个 ViewScoped 页面,它使用 ui:repeat 来布置一些组件。我在这个页面上也有一些指定了操作方法的 h:commandLinks。action 方法执行一些条件逻辑来确定要返回的导航结果。在返回结果并包含“faces-redirect=true”以执行重定向时,当前视图的 bean 在重定向发生之前被重新实例化。
删除 ui:repeat 会导致问题停止,我知道不再看到被调用的 bean 的构造函数。此外,在这种情况下,我不能使用 h:links,因为我希望能够在单击链接的那一刻计算结果。
这是 ui:repeat 的已知错误吗?我四处搜寻,找不到发生这种情况的原因。
下面是一些示例代码,我可以使用 Mojarra JSF 2.1.6 重现它:
例子.xhtml
<h:form>
<h:outputText value="Bean property value: #{exampleBean.property}"/>
<ui:repeat value="#{exampleBean.list}" var="item">
<h:outputText value="#{item}"/>
</ui:repeat>
<br/><h:commandLink value="Action" action="#{exampleBean.someAction()}"/>
<br/><h:commandLink value="Action w/Redirect" action="#{exampleBean.someRedirectAction()}"/>
</h:form>
ExampleBean.java
@ManagedBean(name="exampleBean")
@ViewScoped
public class ExampleBean {
private String property;
private List<String> list;
public ExampleBean() {
System.err.println("Constructor invoked");
list = new ArrayList<String>();
list.add("list item 1");
list.add("list item 2");
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public String someAction() {
System.err.println("someAction() invoked");
if (calculateSomeCondition()) {
return "otherView1";
} else {
return "otherView2";
}
}
public String someRedirectAction() {
System.err.println("someRedirectAction() invoked");
if (calculateSomeCondition()) {
return "otherView1?faces-redirect=true";
} else {
return "otherView2?faces-redirect=true";
}
}
private boolean calculateSomeCondition() {
// some logic to calc true/false
}
}
请注意,otherView1.xhtml 和 otherView2.xhtml 是与 example.xhtml 位于同一目录中的简单文件。
加载页面并单击“操作”链接后在日志中看到的输出:
构造函数调用
了 someAction() 调用
加载页面并单击“Action w/Redirect”链接后在日志中看到的输出:
构造函数调用
了 someRedirectAction() 调用了
构造函数