8

アプリケーションの起動ページの読み込み時に次のエラーが発生します:

 SEVERE: Error Rendering View[/HomeTemplate/equityVolume.xhtml]
javax.el.ELException: /HomeTemplate/equityVolume.xhtml @70,78 value="#{equityBean.scripList}": java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed...

    Caused by: java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed...

ホームページにcssを適用するとこのエラーが発生しますが、cssテンプレートを削除するとエラーが消えます(ただし、cssテンプレートを適用したい)次のエラーの原因となるBeanコードスニペット(デバッグで見つかりました)

public List<MasterScrip> getScripList() {
   HttpServletRequest req=(HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest(); //error line
   HttpSession session=req.getSession();
   type=(String)session.getAttribute("type");...

xhtmlコード:

<h:body>
    <ui:composition template="commonClientLayout.xhtml">

    <ui:define name="contentFile">
            <div id="content">
    <h:form id="frm">...

ui:compositionを削除してタグを定義すると(つまり、cssを適用しない場合)、このエラーは発生しません。このエラーの原因は何ですか?また、どうすれば解決できますか?

編集:

    @PostConstruct
void initialiseSession() {
    if(type!=null)
      {
       if(type.equalsIgnoreCase("losers"))
       {
        scripList=new ArrayList<MasterScrip> ();
        scripList=getScripByPriceLosers(exchange);
       // return scripList;
       }
       else if(type.equalsIgnoreCase("gainers"))
       {
        scripList=new ArrayList<MasterScrip> ();
     scripList=getScripByPriceGainers(exchange);
       // return scripList;
       }
       else
       {
           scripList=new ArrayList<MasterScrip> ();
     scripList=getScripByVolumeType(exchange);
     //  return scripList;
       }
      }
      else
      {
          scripList=new ArrayList<MasterScrip> ();
     scripList=getScripByVolumeType(exchange);
      }

}

    public List<MasterScrip> getScripList() {
       return scripList;

    }

再編集:

 SEVERE: Error Rendering View[/equityVolume.xhtml]
java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.setBufferSize(ResponseFacade.java:275)...

編集:web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
        <param-value>65535</param-value>
    </context-param>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>

    </session-config>
    <welcome-file-list>
        <welcome-file>equityVolume.xhtml</welcome-file>
    </welcome-file-list>
    <security-constraint>
        <display-name>Constraint1</display-name>
        <web-resource-collection>
            <web-resource-name>AdminTemplate</web-resource-name>
            <description/>
            <url-pattern>/AdminTemplate/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>
    <security-constraint>
        <display-name>Constraint2</display-name>
        <web-resource-collection>
            <web-resource-name>ClientTemplate</web-resource-name>
            <description/>
            <url-pattern>/ClientTemplate/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>client</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>DataRealm</realm-name>
        <form-login-config>
            <form-login-page>/equityVolume.xhtml</form-login-page>
            <form-error-page>/errorpage.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <description/>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <description/>
        <role-name>client</role-name>
    </security-role>
</web-app>
4

2 に答える 2

6

あなたはゲッターでビジネスの仕事をするべきではありません。代わりに、Bean(ポスト)コンストラクターで実行してください。

具体的な問題は、サーバーHttpSessionがまだ作成されていない新しい新しいブラウザセッションで比較的大きなページを要求していて、EL式#{equityBean.scripList}がページの比較的遅い位置で参照されているために発生します。

応答バッファはデフォルトで2KBであり、応答が大きいためにオーバーフローすると、コミットされます。これは、すべての応答ヘッダーが送信され、HTML出力の最初の約2KBが送信されることを意味します。その後、#{equityBean.scripList}セッションを取得しようとしているEL式が解決されます。HttpSessionその時点でサーバーがまだ作成されていない場合、サーバーは、後続の要求のためにCookieを維持するために、応答ヘッダーにCookieを設定する必要があります。しかし、応答がすでにコミットされている場合はもちろんそれは不可能です。したがって、この例外。

前述のように、代わりにBeanの(ポスト)コンストラクターで作業を行ってください。または、管理プロパティとして挿入するだけです。

@ManagedProperty("#{type}")
private String type;

それでも例外が発生する場合は、問題2215および2277で説明されているように、「不要な」セッション作成の極端な延期が原因で発生するバグに悩まされている古いバージョンのMojarraを使用している可能性があります。これは、Mojarra2.1.8以降で修正されています。したがって、それ以降(現在は2.1.9)にアップグレードする必要があります。


具体的な問題とは関係なく、getScripList()論理はちなみに臭いです。しかし、それは別の問題/質問の対象です。ELで「type」という名前のセッション属性にアクセスできることをご存知#{type}ですか?JSFバッキングBeanクラスにrawjavax.servlet.*インポートがあるということは、間違った方法で実行している可能性があり、具体的な機能要件を達成するための「JSF風」の方法がもっとある可能性があることを示していることがよくあります。

于 2012-06-08T15:09:39.773 に答える
3

このWebフレームワーク(JSFですか?)はわかりませんが、次のようになります。XHTMLが出力のレンダリングを開始し、いくつかの文字がすでにブラウザに送信されています。これは、ヘッダー全体も送信されたことを意味します。

テンプレートの途中で呼び出しているもの#{equityBean.scripList}(BTW typo)は、次のように呼び出します。

HttpSession session=req.getSession();

このメソッドは、HTTPセッションが存在しない場合に作成します。後続のリクエストでセッションを識別するために、セッションIDを(CookieまたはURLの書き換えを使用して)応答とともにクライアントに返送する必要があります。ただし、応答ヘッダーはすでに送信されているため、サーブレットコンテナはセッションIDを送り返すことができず、さらに大きな問題を回避するために例外をスローします。

どうすればこれを解決できますか?リクエストに関連付けられたセッションがまったくないときに、初めてページをレンダリングしているように見えます。セッションの作成を回避できます。

HttpSession session=req.getSession(false);  //false here!
if(session != null) {
  type=(String)session.getAttribute("type");
}
//handle the case when session or type attribute weren't there

もう1つのアプローチは、コントロールをビューに渡す前に、事前にセッションを作成することです。ただし、のtype属性を確認する必要がありますnull

于 2012-06-08T13:22:22.120 に答える