JAXB とクライアント プロキシを使用して Web サービスを正常に呼び出し、MTOM を使用してバイナリ データを送信する Web サービス クライアントを Java で作成しました。
サービスには SSL が必要になりました。SSL 接続を提供するようにクライアント コードを更新した後、バイナリ アタッチメントを必要としない呼び出しを正常に行うことができますが、バイナリ アタッチメントを必要とする呼び出しはハングします。サービスからの応答はありません。最終的にクライアントがタイムアウトします。
どうすればこれを機能させることができますか? SSL を使用するときに MTOM を有効にするには、何か特別なことをする必要がありますか? このサイトとウェブを検索しましたが、これに関する他のレポートはありません。
サーバー側でネットワーク パケットを監視していた人から少し情報を得ました。私は完全に理解していないので言い換えます.TLSが開始され、データが転送されると彼は言いますが、TLS暗号化ハンドシェイクに再び入り、失速します。彼は、MTOM 用に生成された別個の TLS セッションがあるかどうか疑問に思っています。私のアプリケーションは、すでに TLS セッションが確立されていると考えており、必要な証明書の初期交換を行っていません。それはすべて低レベルのライブラリ コードにあり、ソースがないため、それをチェックする方法がわかりません。
私はWebサービスとSSLに非常に慣れていません。
Web サービスを作成するコードは次のとおりです。
private MyService getService() throws Exception {
SSLHelper.initializeConduitForSSL(new File("d:/keystore.jks"), "jks", "changeit");
final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(MyService.class);
factory.setAddress("https://" + endPoint); // endpoint not shown in this code
service = (MyService)factory.create();
final Client client = ClientProxy.getClient(service);
final HTTPConduit http = (HTTPConduit)client.getConduit();
http.setTlsClientParameters(SSLHelper.getTlsParams());
final Map<String, Object> ctxt = ((BindingProvider)publishingService).getRequestContext();
// Enable HTTP chunking mode, otherwise HttpURLConnection buffers
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
return service;
}
要求を行うには、返されたサービス オブジェクトでメソッドを呼び出します。
SSLHelper は、証明書のセットアップを処理する独自のクラスです。その部分は問題ではないと思うので、そのセットアップ コードはここには含めません。(同じ SSL 構成で他のリクエストを行うことができるので、これは問題ではないと想定しています。)
MTOM 呼び出しの場合、メソッドは次のように指定されたフィールド (適切なセッターを含む) を持つ要求クラスのインスタンスである引数を取ります。
@XmlElement(required = true)
@XmlMimeType("application/octet-stream")
private DataHandler dataHandler;
このクラスを初期化するには、次のようにします。
File file = new File("c:\\somefile.jpg"); //
final DataSource dataSource = new FileDataSource(file);
request.setDataHandler(new DataHandler(dataSource));
DataHandler と FileDataSource は javax.activation パッケージにあります。
最後に一つだけ。サービスの所有者は、MTOM を使用してこの要求を正常に呼び出すことができますが、以下を使用して SSL を有効にしています。
System.setProperty("javax.net.ssl.keyStore", keyStorePath);
System.setProperty("javax.net.ssl.keyStoreType", "jks");
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
同じJVM内で、複数のキーストアを使用してさまざまなWebサービスに接続しているため、それはできません。