JSF 1.2 アプリケーションを JSF 2.1 に移行しています。具体的には、現在 mojorra 2.1.24 を使用しています。
アプリケーションはリクエスト スコープ Bean で構成され、リクエスト間でデータを渡すために、UI コンポーネント内にデータを埋め込みます。
次の動作は、JSF 1.2 ではうまく機能しますが、JSF 2.1 では機能しません。
このページには、次のスニペットが含まれています。
<h:form prependId="false">
<h:inputHidden binding="#{bean.inputHidden}" />
...
<h:panelGroup rendered="#{bean.rendered}">
...
<h:commandLink value="onAction" action="#{bean.onAction}" />
</h:panelGroup>
</h:form>
Bean は次のとおりです。
@ManagedBean
@RequestScoped
public class Bean {
private UIInput inputHidden;
private AItem item;
public setInputHidden(UIInput inputHidden){
this.inputHidden = inputHidden;
if(item != null){
this.inputHidden.setValue(item);
}
}
public AItem getItem(){
return (AItem) getInputHidden().getValue();
}
// other getter/setter
public String onNavToPage(AItem item){
this.item = item;
return "page";
}
public String onAction(){
//... do something
return "";
}
public boolean isRendered(){
return getProcessItem() != null;
}
}
手順は次のとおりです。
page
メソッドbean.onNavToPage
が呼び出されたページに移動します。- ページのレンダリング時に
bean.item
が値として設定されbean.inputHidden
ます。 - ページが表示された後、コマンド リンクが押されます。
bean.inputHidden.getValue()
が null を返し、コマンド リンクが処理されないため、この時点ではコマンド リンクは呼び出されません。ビューの復元フェーズ中に setInputHidden メソッドに渡された inputHidden パラメータに、inputHidden.getValue() == null があり、値が以前にビューに保存されていないことに気付きました。コンポーネントの状態管理で何かが変更されたと思いますが、JSF コードをデバッグしても何が見つかりませんでした。
JSF コードのデバッグ状態がビューに保存される前に、コンポーネントの状態がマスクされていることがわかりました。そのため、ComponentStateHelper.saveState()
すべての状態が配置されている defaultMap ではなく、deltaMap が保存されます。
public Object saveState(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
if(component.initialStateMarked()) {
return saveMap(context, deltaMap);
}
else {
return saveMap(context, defaultMap);
}
}
これはバグですか?そうでない場合、JSF 1.2 の動作を復元して defaultMap を保存するにはどうすればよいですか?
助けてくれてありがとう。