web-dev-qa-db-ja.com

<h:form>を追加すると、Java.lang.IllegalStateException:応答がコミットされた後にセッションを作成できません

<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>を削除すると、例外は消えます。

これはどのように引き起こされ、どうすれば解決できますか?

47
Pier Luigi

これは既知の問題であり、実際に issue 2215 として報告されています。これは、応答バッファがオーバーフローし(コンテンツが大きいため)、セッションが作成される前に応答がコミットされた場合に発生します。これは、モジャラが「不必要な」セッションの作成を可能な限り延期しようとする熱心な試みの結果です(ただし、それ自体は良いことです)。

修正されるまで、いくつかの回避策があります。

  1. HttpServletRequest#getSession() の前に FilterChain#doFilter() を実行するFilterを作成します。利点:JSF構成/コードを変更する必要はありません。欠点:不必要なセッションの作成を自分で避けたい場合。

  2. Beanの(ポスト)コンストラクターまたはtrueリスナーでpreRenderViewを指定して ExternalContext#getSession() を呼び出します。利点:実際には何もありません。欠点:あまりにもハッキング。

  3. 名前が_com.Sun.faces.writeStateAtFormEnd_で値がfalseのコンテキストパラメーターを_web.xml_に追加します。利点:不要なセッション作成は、#1および#2とは対照的に本当に回避されます。欠点:_</h:form>_に達するまで、応答がメモリに完全にバッファリングされるようになりました。フォームが極端に大きくない場合、影響は最小限に抑える必要があります。ただし、_<h:form>_がビューの比較的遅い時点で開始される場合、それでも失敗します。これは#4と組み合わせることができます。

  4. 名前が_javax.faces.FACELETS_BUFFER_SIZE_で、Facelets応答バッファーサイズの値(64KBの場合は_65535_)を持つコンテキストパラメーターを追加して、HTML出力全体または少なくとも_<h:form>_(参照#3)応答バッファーに収まります。長所/短所、#3を参照してください。

  5. 名前が_javax.faces.STATE_SAVING_METHOD_で値がclientのコンテキストパラメーターを_web.xml_に追加します。利点:セッションスコープBeanがない限り、セッションはまったく作成されません。また、潜在的なViewExpiredExceptionケースを即座に解決します。欠点:ネットワーク帯域幅の使用量が増加します。ただし、状態の部分的な保存を使用している場合、影響は最小限に抑えられます。

_<h:form>_を削除すると問題が消える理由については、ビューステートを保存するためにセッションを作成する必要がないためです。


Update:これは重複により issue 2277 Mojarra 2.1.8以降修正されました。そのため、少なくともそのバージョンにアップグレードすることもできます。

83
BalusC

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のja​​vax.faces.jarを置き換えます。

6
Gaspar Kuhnen

私の場合(myfaces-2.2.8およびTomcat 8.0.23)、問題はwelcome-fileweb.xmlのタイプミスでした。私が見たデバッグ中に、Tomcatは予想通り404を作成しましたが、どういうわけかmyfacesはセッションにアクセスしようとし、それがJava.lang.IllegalStateException: Cannot create a session after the response has been committedを引き起こしました。 welcome-fileweb.xmlで有効なページを使用すると、問題が修正されました。

3
hinneLinks

<f:view>要素の前後に</f:view>およびh:formを追加し、さらにjsfタグのhtmlタグへのリンクを追加する必要があります。

<html xmlns:f="http://Java.Sun.com/jsf/core">

これが機能するために。

0
joeblow