状況は、いくつかのコンポーネントをレイアウトするために ui:repeat を使用する ViewScoped ページがあることです。このページにも、アクション メソッドが指定された h:commandLinks がいくつかあります。アクション メソッドは、条件付きロジックを実行して、返すナビゲーションの結果を決定します。結果を返し、リダイレクトを実行するために「faces-redirect=true」を含めると、リダイレクトが発生する前に現在のビューの Bean が再インスタンス化されます。
ui:repeat を削除すると、問題が停止します。Bean のコンストラクターが呼び出されていることがわかります。また、リンクがクリックされた瞬間に結果を計算できるようにしたいので、この場合は h:links を使用できません。
これは ui:repeat の既知のバグですか? 私は周りを検索しましたが、なぜこれが起こっているのかわかりませんでした。
Mojarra JSF 2.1.6 を使用してこれを再現できるサンプル コードを次に示します。
example.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 と同じディレクトリにある単純なファイルであることに注意してください。
ページをロードして「アクション」リンクをクリックしたときにログに表示される出力:
Constructor
invoked someAction() invoked
ページをロードして「 Action w/Redirect」リンクをクリックしたときにログに表示される
出力
: