<h:form>
を追加した後、非常に単純なJSF 2ページで次の例外に直面しています。
Java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.Apache.catalina.connector.Request.doGetSession(Request.Java:2758)
at org.Apache.catalina.connector.Request.getSession(Request.Java:2268)
Tomcat 7.0.22およびJDK 7でMojarra 2.1.3およびPrimeFaces3.0M4を使用しています。
このページは非常に基本的なデータテーブルです。
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://Java.Sun.com/jsf/html"
xmlns:f="http://Java.Sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:dataTable var="car" value="#{tableBean.cars}">
......
</p:dataTable>
</h:form>
</h:body>
</html>
ページはブラウザに正しく表示されますが、コンソールには例外が表示されます。 <h:form>
を削除すると、例外は消えます。
これはどのように引き起こされ、どうすれば解決できますか?
これは既知の問題であり、実際に issue 2215 として報告されています。これは、応答バッファがオーバーフローし(コンテンツが大きいため)、セッションが作成される前に応答がコミットされた場合に発生します。これは、モジャラが「不必要な」セッションの作成を可能な限り延期しようとする熱心な試みの結果です(ただし、それ自体は良いことです)。
修正されるまで、いくつかの回避策があります。
HttpServletRequest#getSession()
の前に FilterChain#doFilter()
を実行するFilter
を作成します。利点:JSF構成/コードを変更する必要はありません。欠点:不必要なセッションの作成を自分で避けたい場合。
Beanの(ポスト)コンストラクターまたはtrue
リスナーでpreRenderView
を指定して ExternalContext#getSession()
を呼び出します。利点:実際には何もありません。欠点:あまりにもハッキング。
名前が_com.Sun.faces.writeStateAtFormEnd
_で値がfalse
のコンテキストパラメーターを_web.xml
_に追加します。利点:不要なセッション作成は、#1および#2とは対照的に本当に回避されます。欠点:_</h:form>
_に達するまで、応答がメモリに完全にバッファリングされるようになりました。フォームが極端に大きくない場合、影響は最小限に抑える必要があります。ただし、_<h:form>
_がビューの比較的遅い時点で開始される場合、それでも失敗します。これは#4と組み合わせることができます。
名前が_javax.faces.FACELETS_BUFFER_SIZE
_で、Facelets応答バッファーサイズの値(64KBの場合は_65535
_)を持つコンテキストパラメーターを追加して、HTML出力全体または少なくとも_<h:form>
_(参照#3)応答バッファーに収まります。長所/短所、#3を参照してください。
名前が_javax.faces.STATE_SAVING_METHOD
_で値がclient
のコンテキストパラメーターを_web.xml
_に追加します。利点:セッションスコープBeanがない限り、セッションはまったく作成されません。また、潜在的なViewExpiredException
ケースを即座に解決します。欠点:ネットワーク帯域幅の使用量が増加します。ただし、状態の部分的な保存を使用している場合、影響は最小限に抑えられます。
_<h:form>
_を削除すると問題が消える理由については、ビューステートを保存するためにセッションを作成する必要がないためです。
Update:これは重複により issue 2277 Mojarra 2.1.8以降修正されました。そのため、少なくともそのバージョンにアップグレードすることもできます。
Javax.facesの昨日リリースされた新しいバージョン2.1.21では、この問題は解消されたようです。新しいバージョンを宣言します。
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.21</version>
</dependency>
glassfishモジュールフォルダー内のjavax.faces.jarを置き換え、新しいバージョン2.1.21のjavax.faces.jarを置き換えます。
私の場合(myfaces-2.2.8およびTomcat 8.0.23)、問題はwelcome-file
のweb.xml
のタイプミスでした。私が見たデバッグ中に、Tomcatは予想通り404を作成しましたが、どういうわけかmyfacesはセッションにアクセスしようとし、それがJava.lang.IllegalStateException: Cannot create a session after the response has been committed
を引き起こしました。 welcome-file
のweb.xml
で有効なページを使用すると、問題が修正されました。
<f:view>
要素の前後に</f:view>
およびh:form
を追加し、さらにjsfタグのhtmlタグへのリンクを追加する必要があります。
<html xmlns:f="http://Java.Sun.com/jsf/core">
これが機能するために。