1

現在、2つのハンドラーがあります。1つはロギング用で、もう1つはSOAPメッセージに署名するためのものです(これは本質的にSOAPメッセージを改ざんします)。ハンドラチェーンがない場合、MTOMは期待どおりに機能し、base64バイナリコンテンツをインライン化するのではなく、バイナリコンテンツへの参照を挿入します。

ハンドラーを導入するとすぐに、MTOMコンテンツがインラインに含まれるようになりました。

ハンドラーを使用してSOAPメッセージに署名することは可能ですか、それともこれを行うためのより適切な手段がありますか?

アップデート1 完全なソースを投稿できません。ただし、基本的には、カスタムSOAPHandlerの実装です。タイムスタンプ(ヘッダー内)、カスタムヘッダー、およびSOAP本体に対していくつかの基本的なXMLDsigタイプの操作を実行します。結果のダイジェスト値は、ヘッダーの署名要素に挿入されます。

ロガーに関しては、これも単純なSOAPHandlerです。それまたは署名ハンドラーのいずれかが排他的に使用される場合、結果は同じであり、バイト内容がインライン化されたMTOMメッセージです。私が行った唯一の進歩は、ロギングにMessageHandlerを使用することでした。これにより、(バイトコンテンツがインライン化されていても)SOAPエンベロープを出力し、MTOM分離を維持することができました。したがって、実際には解決策ではありませんが、SOAPメッセージの変更を下位レベルで行う必要があることを示しています。これは私をチューブの道へと導いてくれます。

アップデート2

以下は、MessageHandlerアプローチの例です。生のHTTPダンプには複数の部分からなるメッセージが含まれているのに対し、実際の出力はbase64にインライン化されていることがわかります。この実装と実装の唯一の違いSOAPHandlerは、実際のHTTPリクエストが単一部分のインラインMTOMメッセージに変更されることです。

@Override
public boolean handleMessage(MessageHandlerContext context) {

  HttpTransportPipe.dump = true;

  Boolean isOutgoing = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

  if (isOutgoing) {
    System.out.println("\nOutbound message:");
    XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out);
    try {
      context.getMessage().writeTo(writer);
    } catch (XMLStreamException e) {
      throw new IllegalStateException("Unable to write");
    }
  } else {
    System.out.println("\nInbound message:");
  }
  return true;
}
4

2 に答える 2

3

MTOMによって転送された画像を受け入れる簡単なサービスをまとめて、問題を再現しようとしました。ハンドラーを設定する前にMTOM対応コードを配置すると、メッセージが適切にエンコードされることがわかりました。最初にハンドラーを設定すると、設定されません。ここで、適切に機能するクライアントコードを設定します。

Service service = Service.create(url, qname);

Greeting greeting = service.getPort(Greeting.class);

BindingProvider bp = (BindingProvider) greeting;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);

service.setHandlerResolver(new HandlerResolver() {
    @SuppressWarnings("rawtypes")
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerList = new ArrayList<Handler>();
        handlerList.add(new RGBSOAPHandler());
        return handlerList;
    }
});

RGBSOAPHandler別のSO回答から取得したサンプルコードはどこにありますか。

編集:また、サービスではなくバインディングにハンドラーを設定しようとすると、同じ問題が発生します。したがって、次のようになります。

Service service = Service.create(url, qname);

Greeting greeting = service.getPort(Greeting.class);

BindingProvider bp = (BindingProvider) greeting;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);

List<Handler> handlerList = new ArrayList<Handler>();
handlerList.add(new RGBSOAPHandler());
binding.setHandlerChain(handlerList);

次に、私のファイルはインラインでエンコードされます。理由はわかりませんが、答えは「やらないで」だと思います。オブジェクトにハンドラーを設定しますService

于 2012-08-16T17:10:31.607 に答える
1

フレームワークとハンドラーの動作方法によって制限されているようです。この段階では、私の唯一の選択肢はより低いレベルに行くことだと思います。チューブの使用を確認しましたが、同じ動作が見られたため、リクエストのXMLを操作しようとしても失敗したように見えます。そのため、当面はハンドラーを放棄し、コーデックを使用して自分が求めていることを実行できるかどうかを下位レベルで調査する必要があります。MTOMの実装は、バイトレベルで私が求めていることを実行できるように思えます。

http://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/com/sun/xml/ws/encoding/MtomCodec.html

これは動作するのにそれほど複雑ではないと想像しましたが、コーデックの面での進捗状況に応じて更新されます。

@David:ハンドラーの面で助けてくれてありがとう。しかし、そのレベルでは解決策がないように見えます。

アップデート1

私の目的のために働く別の解決策を思いついた。

  1. SOAPHandlerを使用してSOAPメッセージの必要な部分に署名します。
  2. 新しいSOAPHandlerを作成し、結果のメッセージを受け取り、誤ってインライン化されたバイナリコンテンツを手動で抽出します。
  3. 次に、を作成し、AttachmentPartステップ2のコンテンツをその中に挿入します。Base64でエンコードされたテキストも必要です。これは便利です。次に、の参照UUIDAttachmentPartが割り当てられContent-Idます。
  4. 次に、次の行に沿って、UUIDを参照するSOAP本体のBase64コンテンツの代わりに新しい要素を作成します。

    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:UUID!!!"></xop:Include> 
    

これまではちょっとした壮大な旅だったので、おそらくこれについてブログ記事を書くでしょう。これは最善の解決策ではありませんでしたが、チューブ/コーデックのパスをたどるよりも確かに簡単でした。

于 2012-08-20T00:33:06.560 に答える