20

JSF ページの ajax リクエストに問題があります。ボタンをクリックすると、次の例外が発生します。

SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: CDATA tags may not nest
    at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.startCDATA(HtmlResponseWriter.java:630)
    at javax.faces.context.ResponseWriterWrapper.startCDATA(ResponseWriterWrapper.java:172)
    at javax.faces.context.PartialResponseWriter.startError(PartialResponseWriter.java:342)
    at org.primefaces.context.PrimePartialResponseWriter.startError(PrimePartialResponseWriter.java:210)
    at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:200)
    at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)

オブジェクトに問題があると思いますString。サイトに表示される JPA エンティティ プロパティをハードコードすると、すべて問題ないからです。ただし、エンティティがデータベース (PostgreSQL) から取得されると、前述の例外がスローされます。

JSF コード:

<p:column>
    <f:facet name="header">
        Akcja
    </f:facet>
    <h:commandButton actionListener="#{mBDocumentMigration.actionEdit(object)}" value="Edytuj" rendered="#{mBDocumentMigration.editingObject == null}" >
        <f:ajax render="@form" execute="@form" />
    </h:commandButton>
    <h:commandButton action="#{mBDocumentMigration.actionZapisz}" value="Zapisz" rendered="#{mBDocumentMigration.editingObject != null}" >
    <f:ajax render="@form"  execute="@this" />
    </h:commandButton>
</p:column>
4

6 に答える 6

50

コードのバグが原因で、JSF 応答のレンダリング中に例外がスローされます。しかし、Mojarra は組み込みの ajax 例外ハンドラーでこの例外を適切に処理できず、別の例外が発生し、元の例外に関するすべての詳細が隠されています。

スタック トレースをよく見てください。一番下から開始して、コール スタックを追跡します。

at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)

したがって、レンダリング応答フェーズ中に発生しました。さて、次の行 (その上の行) を見てください。

at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)

ねえ、Mojarra のビルトイン ajax 例外ハンドラを通過しました AjaxExceptionHandlerImpl! これは、ajax リクエスト中に例外が発生した場合にのみ呼び出されます。では、次の行を下から上に読んでください。

at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.startCDATA(HtmlResponseWriter.java:630)
at javax.faces.context.ResponseWriterWrapper.startCDATA(ResponseWriterWrapper.java:172)
at javax.faces.context.PartialResponseWriter.startError(PartialResponseWriter.java:342)
at org.primefaces.context.PrimePartialResponseWriter.startError(PrimePartialResponseWriter.java:210)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:200)

したがって、エラー情報を ajax レスポンスに書き込もうとしています。この情報は CDATA ブロックに入れる必要があります。ただし、明らかに既に CDATA ブロックが開いているため、CDATA ブロックの開始は次のように失敗しました。

java.lang.IllegalStateException: CDATA tags may not nest

これは、ajax 応答の書き込み中に例外が発生したことを示しています。おそらく、HTML 出力の生成中にのみ呼び出されるゲッター メソッドでビジネス ロジックを実行しているためです。したがって、プロセスは次のようになる可能性が最も高いです。

  1. JSF は RENDER_RESPONSE フェーズに入ります。
  2. JSF は HTML 出力を生成する必要があります。
  3. すべての<f:ajax render="some">(または) について、生成された HTML 出力をCDATA ブロック<p:ajax update="some">内に含む XML ブロックを作成する必要があります(XML 出力を構文的に有効に保つため)。したがって、CDATA ブロックを開始する必要があります。<update id="some">
  4. valueHTML 出力を CDATA ブロックに生成する際、すべての UI コンポーネントの属性を含め、すべてのレンダリング時の EL 式が評価されます。
  5. どこかで、EL 式の背後にあるゲッターが、独自のコードのバグが原因で例外をスローしました。
  6. JSF は即座に HTML 出力の生成を停止し、CDATA ブロックを閉じませんでした。HTTP 応答には中途半端なデータが含まれています。
  7. AjaxExceptionHandlerImplがトリガーされます。
  8. AjaxExceptionHandlerImpl例外/エラーの詳細を応答に書き込む必要があります。ただし、応答が既に書き込まれているかどうかはチェックされませんでした。やみくもに CDATA ブロックを開こうとしますが、既に開かれているために失敗します。表示されている例外をスローし、処理しようとした実際の根本的な例外に関するすべての詳細を隠しています。

ご覧のとおり、問題は 2 つあります。

  1. JSF レンダラーは、応答を中途半端なままにしておくべきではありませんでした。
  2. MojarraAjaxExceptionHandlerImplは、応答の状態をチェック/検証する必要があります。

Mojarra のビルトイン ajax 例外ハンドラーを、スタック トレースをすぐに出力するカスタムハンドラー、または中途半端な ajax 応答を検出してクリーニングできるOmniFacesFullAjaxExceptionHandlerに置き換えると、コードのバグによって引き起こされた実際の根本的な原因が最終的に明らかになり、表示されます。 . 前に述べたように、ゲッター メソッドでビジネス ロジックを実行することが原因である可能性が高く、これは悪い習慣です。

于 2013-07-30T12:01:32.103 に答える
0

私はあなたと同じ問題を抱えていました。バッキング Bean のオートコンプリート コンポーネントでバインディングを使用すると、正常に機能しました。

<p:autoComplete id="autocomplete" binding="#{searchBean.compui}" title="Find" value="#{searchBean.searchfor}" forceSelection="false" queryDelay="30" dropdown="true" maxResults="20" emptyMessage="None" completeMethod="#{searchBean.complete}" style="width: 90%;"/>
<p:commandButton id="cmdsearch" value="#{msg.search}" action="#{searchBean.search}" update="tblprocresults" icon="ui-icon-zoomin"/>

そしてバッキングビーンで

private AutoComplete compui;
//compui is initialized when bean is constructed
    public AutoComplete getCompui() {
            return compui;
        }

        public void setCompui(AutoComplete compui) {
            this.compui = compui;
        }
于 2016-08-23T05:17:01.187 に答える
-2

サーバーログにも表示される場合はjava.lang.ClassCastException: com.sun.faces.facelets.compiler.UIInstructions cannot be cast to org.primefaces.component.tree.UITreeNode、追加します

<context-param>
  <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
  <param-value>true</param-value>
</context-param>

/WEB-INF/web.xml

于 2014-06-01T12:05:02.880 に答える
-2

CDATA の問題は PrimeFaces の問題ではなく、部分的な出力を提供する責任を負う JSF 実装に関連しています。そのJSFプロパティに置き換えてください;)

于 2014-04-25T11:02:32.313 に答える
-4

Tomcat 7 で同様の実行を取り除くための私の経験は次のとおりです。jsf でメソッドを呼び出す場合は、パラメーターがなくても () を追加する必要があります。

この例外ですが、jetty を使用している場合は表示されません

編集:この例外は排除されましたが、別の例外が発生しました:

java.lang.NoSuchMethodError: javax.el.ELResolver.invoke(Ljavax/el/ELContext;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;

調査した結果、Tomcat 7 はそれ自体で EL 依存関係をもたらすことがわかったので、pom.xml の他の依存関係は次のようになります。

<dependency>
    <groupId>javax.el</groupId>
    <artifactId>el-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

混合を避けるために削除する必要があります。

その後、デフォルトで tomcat 6 を起動するtomcat7:run代わりに、Run as - in Eclipse でtomcat7 を起動する必要があります。tomcat:run

私の環境:

  • エクリプス・ケプラー
  • JDK1.7.0_45
  • Maven 3.1.1
于 2014-10-22T13:35:47.220 に答える