- 環境
- CentOS Linux release 7.8.2003 (Core)
- Eclipse IDE for Enterprise Java Developers.Version: 2020-03 (4.15.0)
- openjdk version "11.0.7" 2020-04-14 LTS
- JSF 2.3.9
事象 : ページを表示したらHTTPSステータス500になった
2020-08-10T15:17:17.299+0900|警告: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
javax.faces.application.ViewExpiredException: viewId:/base.jsf - ビュー /base.jsf を復元できませんでした。
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:194)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:109)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:177)
at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:707)
...省略...
原因 : h:buttonタグのonclick属性にEL式を書いているから
...省略...
<h:button value="アップロード" onclick="#{uploadBean.onClick}"/>
...省略...
...省略...
/**
* onClick属性用に出力するJavaScriptコードを取得する.
* @return JavaScriptコード.
*/
public String getOnClick() {
StringBuilder builder = new StringBuilder();
builder.append("window.open('upload.jsf");
// ...省略...
return builder.toString();
}
...省略...
EL式を書くとうまくいかない理由がよくわからない・・・・ドキュメントに書いてあることが何を言いたのかよくわからないからだろうか?
誰かわかりやすく説明してほしい・・・。
The entire target URL string must be processed by a call to the encodeResourceURL() method of the ExternalContext. The name of the UIParameter goes on the left hand side, and the value of the UIParameter on the right hand side. The name and the value must be URLEncoded. Each UIParameter instance is separeted by an ampersand, as dictated in the URL spec. The final encoded result will be written out to the onclick attribute of the button as "window.location.href = ''". If the developer has specified a custom onlclick the window.location.href name/value pair will be appended at the end of the developer specified script.
button(JSF 2.1 View Declaration Language: Facelets Variant)
(ざっくり訳)
ターゲットURLは、ExternalContextのencodeResourceURLメソッドへの呼び出しによって処理される必要があります。
UIParameterの名前は左側に表示され、UIParameterの値は右側に表示されます。名前と値はURLEEncodedでなければなりません。各UIParameterインスタンスは、URL仕様の指示に従ってアンパサンドで区切られます。
エンコードされた最終結果は、ボタンのonclick属性に"window.location.href = ''"として書き出されます。
開発者がonlclickを指定した場合は、window.location.hrefの名前と値のペアがスクリプトの最後に追加されます。
対応 : inputタグのtype="button"に変える
...省略...
<input type="button" value="アップロード" onclick="#{uploadBean.onClick}" />
...省略...
疑問 : h:buttonタグのonclick属性にEL式を書いてうまくいくこともある
<h:button value="OK" onclick="submit('#{uploadBean.key}');" />
...省略...
public String getKey() {
return "formId:file";
}
...省略...
<input type="button" onclick="submit('formId:file');window.location.href='/tryJsf/upload.jsf'; return false;" value="OK">