11

私はいくつかのWebサービスベースのアプリケーションに取り組んでおり、ApacheCXFのアンマーシャリングについて質問があります。私たちのプロジェクトでは、CXF2.4.1バージョンを使用しています。

一部のSOAP要求が正しくない場合(たとえば、一部のフィールドが数値ではなくテキストである場合)、CXFは標準のSOAPFaultExceptionをスローし、SOAP応答は次のような標準フィールドで構築されます。

<soap:Fault>
    <faultcode>soap:Client</faultcode>
    <faultstring>Unmarshalling Error: some field missing</faultstring>
</soap:Fault>

プロジェクトの要件によると、障害が発生した場合、システムは次のような他の形式で対応する必要があります。

<soap:body>
    <ResponseState>
        <ErrorCode>2732</ErrorCode>
        <ErrorMessage>Unmarshalling Error: some field missing</ErrorMessage>
        <ErrorDetails> some details </ErrorDetails>
        <some other fields>
        ...
    </ResponseState>
</soap:body>

したがって、問題は、このエラー処理をなんとかしてオーバーライドし、デフォルトではなく自分の形式で応答するにはどうすればよいかということです。

前もって感謝します。

PSいくつかのValidationEventHandlerプリンシパルを調べようとしましたが、CXF2.0以降では他の方法で機能します。

4

3 に答える 3

10

さて、多くの調査の結果、CXFエラー処理のいくつかの方法を見つけました。

*。ValidationEventHandlerを使用すると、標準の例外の代わりに独自の例外をスローすることができます。ただし、応答動作を変更したり、SOAP応答形式を変更したりすることはできません。

*。エラー処理を変更する別の方法は、独自のインターセプターを作成することです。CXFワークフローは、インターセプターのチェーン上に構築されています。インターセプターには、inInterceptor、outInterceptor、inFaultInterceptor、outFaultInterceptorの4種類があります。

いくつかのスマートハックを使用すると、独自のインターセプターを作成して(チェーンに追加して)ワークフローを変更し、チェーンから標準のインターセプターを削除できます(クラス名がわかっている場合)。したがって、実際に必要なことは何でもできます。

ただし、これらすべてのインターセプターが手動で応答をマーシャリングする限り(xmlWriter.writeStartElement()など)、フローフェーズごとに独自のインターセプターを作成することは大きな課題になる可能性があります。それは本当に膨大な量の作業になる可能性があります。

残念ながら、CXFインターセプターについての適切なリファレンスは見つかりませんでした。

もう1つ、SOAPFaultExceptionの代わりに通常の応答を返す必要がある場合は、この応答を返す実際のサービス、要求で渡されたサービスパラメーターなどの追加情報が必要になる場合があります。インターセプターのアクセス可能なパラメーターでこの情報が見つかりません。そして、確かに、そうすることで、実際の例外ではなくOKを返すクライアントコードをごまかします。

*。すべてのパラメーターをテキストとして使用してwsdlを設計することは、あまり良い解決策ではない可能性があります。

a。wsdlにデータ型と検証ルールがない場合、サービスの利用者は本当に混乱する可能性があります。

b。検証のために「車輪の再発明」を行う必要があります。つまり、複雑なルールでは非常に難しい独自のバリデーターをコーディングする必要があります。同時に、XSDにはこのすべての検証が実装され、十分にテストされています。

そして最後に私の状況について:私たちはそれを要件マネージャーと話し合い、XMLスキーマ要件が要求に違反した場合にCXFが独自の標準例外をスローすることを許可することにしました。XSD検証のすべての機能を使用しており、複雑で無駄な作業に時間を無駄にしないため、これは優れたソリューションです。

答えてくれた@ericacmに感謝します。

于 2012-04-19T12:06:36.273 に答える
1

ValidationEventHandlerJAX-WS障害仕様に準拠する障害を使用してスローするデフォルトよりも優れたエラー応答を確実に生成できます。しかし、それはあなたに非常に多くのカスタマイズを可能にするだけです-あなたが制御できないいくつかの要素があるでしょう。たとえば、私のアプリの1つからのValidationEventHandler応答は次のとおりです。

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Client</faultcode>
         <faultstring>Errors in request</faultstring>
         <detail>
            <ns2:ValidationFault xmlns:ns2="http://notification.ws.foo.com/">
               <errors>
                  <error>
                     <inputElement>topicId</inputElement>
                     <errorMessage>java.lang.NumberFormatException: For input string: "" [line:6]</errorMessage>
                  </error>
               </errors>
            </ns2:ValidationFault>
         </detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

<soap:Fault>, <faultcode> and <faultstring>要素については何もできません。しかし、から<ValidationFault>まですべて</ValidationFault>がカスタムです。

応答をより詳細に制御する必要がある場合は、フィールドタイプを数値から文字列に変更してから、アンマーシャラーにエラーをキャッチさせるのではなく、コードで検証を行う必要があります。

はい、同意します。文字列にするのは面倒ですが、応答が上記で指定したものとまったく同じである必要がある場合は、JAX-WSレイヤーよりもCXFを深く掘り下げることなくしては不可能です(たとえば、インターセプターを使用)。 。

于 2012-04-17T22:19:35.103 に答える
0

別のオプションは、CXF変換機能を使用することです

<entry key="Fault" value="ResponseState=..."/>

これにより、サーバーからの元の障害が他の障害にマップされ、クライアントが受け入れることができるようになります。

于 2018-04-04T10:06:47.360 に答える