12

WSDLで記述されたWebサービスにアクセスするJavaアプリケーション用のモジュールを作成しようとしています。ソースWSDLは、ASP.NETWebサービスであると私が信じているものから直接ダウンロードされました。サービスURLは.asmx拡張子で終わり、ブラウザーでサービスURLを表示すると、WSDLのダウンロードに使用できるリンクが表示されます。

私にとって重要な要件は、再コンパイルせずにサービスURLを切り替えることができることです。私に与えられたURLは明らかにテストサーバーであり、本番環境で使用する本番URLが与えられることを私は知っています。また、テスト用のモックサーバーを自分で作成し、サービスが移動された場合に再コンパイルせずに、将来的に新しいURLを指定できるようにしたいと考えています。実際、アプリケーションをインストールして、異なるURLでWebサービスの複数のインスタンスをインスタンス化できるようにしたいと思います。

しかし、私の概念は、wsimportツールが私のために行っていることと一致していないようです。ここでのf1shの回答に続いて、ダウンロードしたWSDLから次のコマンドを使用してJavaコードを生成しました。

wsimport -Xnocompile -keep -b binding.xml wsdlFile.wsdl

私が見つけたのは、生成されたコードに、ダウンロードしたwsdlFile.wsdlへのハードコードされた参照が含まれていることです。これにはサービスのURLが含まれています。このアプリケーションは、実行時にWSDLファイルを編集して構成できるようには実行されません。ビルド時にアプリケーションにコンパイルされ、インスタンス化時にサービスURLを設定できるコードが必要です。

実行時にWSDLを解析する必要がある理由が完全にはわかりません。WSDLがWebサービスにアクセスできるコードを生成するのに十分な情報を提供することは私の理解でした。そのため、サービスURL以外の生成されたコードに何が提供されているのかわかりません。また、サービスURLがで提供されない理由もわかりません。コンストラクター、または生成されたWebサービスクラスのメソッドを介して構成可能。私は何かが欠けているに違いありません。

このシナリオの一般的な方法は何ですか?ほとんどの人は、使用する個々のURLごとにコードを再生成しますか?コードは実行時に生成されますか?構成可能なURLを使用してクライアントコードを構築するために使用できる別のWSDLツールはありますか?

4

2 に答える 2

10

この答えは数日間私を避けてきましたが、どういうわけか質問を書くという行為は常に答えを見つけることに焦点を当てており、さらにいくつかのウェブ検索がそれを指摘しています:

http://www.fransvanbuul.net/?p=98

wsimportは、javax.xml.ws.Serviceを拡張するクラスcom.example.WebServiceを作成したようです。このWebServiceクラスには2つのコンストラクターがあります。no-argコンストラクターは、私が生成した元のWSDLを使用するためにfile://URLでハードコーディングされています。(wsimportコマンドラインでhttps:// URLを指定した場合、それはハードコーディングされたURLになると思います。)または、2つの引数のコンストラクターを使用して、インスタンス化時にWSDLURLを指定できます。このアプローチでは、2番目の引数としてjavax.xml.namespace.QNameオブジェクトも指定する必要がありますが、これはまだ理解していません。

この2引数のコンストラクターを使用すると、おそらく私の問題は解決します。

JDK 1.6から使用しているwsimportは、JAX-WSパッケージの一部のようです。最近のバージョンのJDK1.6にはJAX-WS2.1が含まれており、JAX-WS2.2はこの質問で提起している問題に対処します。

この状況の残りの一部またはすべてを説明する回答を喜んで受け入れます。実行時にWSDLが必要な理由はまだわかりません。より実際的には、誰かが2つの引数のコンストラクターを使用する方法、またはJDK1.6とJAX-WS2.2を使用してコードを生成する方法を教えてくれると役に立ちます。

于 2010-08-25T16:44:47.403 に答える
7

このアプローチでは、2番目の引数としてjavax.xml.namespace.QNameオブジェクトも指定する必要がありますが、これはまだ理解していません。

生成されたソースから1つをコピーします。AQNameはXML修飾名であり、「一意の」IDです。

実行時にWSDLが必要な理由はまだわかりません。

確かにわかっているとは言えませんが、WSDLは基本的にスキーマです。それを提供することで、JAX-WSにSOAP応答を検証するメカニズムを提供していると思います。JAXBバインディングはこれを行うのに十分ではないと思います。

生成されたサービスで常に2つの引数のコンストラクターを使用して、ClassLoader.getResourceメソッドを介してURLを提供し、WSDLをjarに埋め込みます。他のスキーマと同様に、これにリモートURLまたはファイルシステムURLを使用することは、最適とは言えません。

実行時にエンドポイントを設定する方法については、次の質問を参照してください。

HelloService service = new HelloService();
Hello port = service.getHelloPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(
      BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
      "http://foo:8086/HelloWhatever");
String response = port.sayHello(name);
于 2010-08-25T19:30:38.153 に答える