3

追加の Web コンテナー スレッドを消費せずに、単一の WebContainer 内であるサーブレットから別のサーブレットに新しい SOAP 要求を送信する既知の方法はありますか?

これまでのところ、カスタマイズされたリクエストとレスポンスで RequestDispatcher.include(request, response) を使用してみました。これにより、独自の入力を提供し、呼び出し先の出力をインターセプトできます。これにより、(バッファに書き込むカスタム HttpServletResponse クラスを使用して) 問題なく出力をインターセプトできますが、この方法でカスタマイズされた入力を送信することはできませんでした。HttpServletRequestWrapper の拡張機能を使用して、(アプリケーションへの元の要求ではなく) サードパーティ アプリケーションに独自の入力を提供していますが、WebSphere または Axis のいずれかがラッパーを破棄しているように見えるため、代わりに SOAP エラーが発生します。有効な応答。わかりやすくするために、元のリクエストを呼び出し先に転送する必要はありません (これは JSONP GET リクエストです)。

この方法のバリエーションはありますか? 単一の Web コンテナ内でリクエストを送信するまったく別の方法はありますか?

回答してくださった方々、どうもありがとうございました。

コンテキストとして、WebSphere Application Server で実行する JSON/REST Web サービスを作成しています。これは、Axis 2 で SOAP 経由でサード パーティ製品を呼び出します。残念ながら、このサード パーティ製品は、それ自体にもかかわらず、SOAP HTTP インターフェース経由でしか利用できません。同じ WebSphere Web コンテナー内で実行される Java サーブレットです。

以前は、サードパーティ製品の WSDL に基づいて SOAP プロキシ ジェネレータで生成された HTTP プロキシを使用して、このアプリケーションを呼び出していました。これは正常に動作しますが、サービスへの 1 回の呼び出しが 2 つの Web コンテナー スレッドを消費することを意味し、これは重大な脆弱性です。Web コンテナーのスレッド プールがいっぱいになると、サード パーティ アプリケーションが応答するまで、サーブレットへの要求がスレッドを保持しているため、サーブレットが作成した HTTP 要求を処理するためのスレッドを使用できないため、サーブレットはそれを行うことができません。

更新: 私はさらにいくつかのテストを行い、REST サービスへのこのタイプの転送を正常に行うことができました。合成の ServletRequest と ServletResponse を使用して REST/JSON サービスにクエリを実行できるため、呼び出す製品が Axis SOAP インターフェースを使用していない場合でも、本来の目的を達成できます。「SOAPAction ヘッダーが見つかりません!」というメッセージが常に表示されるため、Axis が SOAPAction ヘッダーを予想していたのとは異なる場所で探しているようです。合成リクエストに SOAPACtion ヘッダーを追加したにもかかわらず、障害メッセージが返されました (SOAPAction ヘッダーが実際に追加されていることを確認しました)。

4

1 に答える 1

0

「欠落している」SOAPActionヘッダーが原因でサービスをAxisで動作させることができなかった理由は、WebSphereまたはAxisとはまったく関係がないことがわかりました。どういうわけか2つの同等の文字列を比較し、それらが異なると言っていたのはConcurrentHasMapでした。そのため、AxisがSOAPActionヘッダーを検索したときにSOAPActionヘッダーが返されることはありませんでした。これを回避するために、「SOAPAction」でクエリをテストし、応答をハードコーディングしました。

したがって、今後の参考のために、ここで私が使用した一般的な設定を示します。

  1. コンストラクターで提供されるHttpServletRequest別のクラスをラップする実装クラスを作成します。HttpServletRequestこのクラスではgetHeader、SOAPActionヘッダーのリクエストをキャッチするためにメソッドがオーバーライドされ、他のヘッダーリクエストが元のリクエストに転送される場合があります(AxisはSOAPActionヘッダー以外のものを探していないようです)。またgetInputStream、固定テキストエンコーディングを使用してバイトバッファから読み取るだけの独自のServletInputStream実装をgetContentLength返すメソッドと、データと一致する長さを返すメソッドをオーバーライドしました。

  2. getWriterメソッドとgetOutputStreamメソッドのみを正しく実装するHttpServletResponseを実装するクラスを作成します。このメソッドは、出力をバイトバッファに記録getOutputStreamするカスタム実装を返します。ServletOutputStreamこのgetWriterメソッドは、によって返されるのと同じServletOutputStreamに書き込む特別なPrintWriterを返しましたgetOutputStream。ただし、このライターは書き込み後に常にフラッシュする必要がありました。なぜそうなったのかわかりません。

  3. を使用してリクエストをディスパッチする前RequestDispatcher.include(request, response)に、合成をでラップHttpServletRequestしましたHttpServletRequestWrapper。これは奇妙なことに役立つようです。次にRequestDispatcher.include(request, response)、通常の方法で使用し、カスタムServletOutputStreamのバイトバッファからSOAPサービスの出力を読み取って、HTTPリクエストを発行した場合と同じように処理しました。

于 2012-08-28T14:02:41.180 に答える