46

いくつかの機能 (バグ報告など) に SOAP サービスを利用するファット クライアントを作成しています。

JAX-WS は正常に動作していますが、デフォルトでは (少なくとも netbeans では)、サービスが初期化されるたびにリモート サーバーから WSDL をフェッチします。これがバージョン管理のサポートなどを提供するのに役立つことを期待していますが、それは私が望んでいるものではありません。

wsdllocation引数を wsimport に追加して、生成されたクラスがローカル リソースを指すようにしました。次のスニペットは、ApplicationService.java から WSDL リソースをロードする URL です。

baseUrl = net.example.ApplicationService.class.getResource(".");
url = new URL(baseUrl, "service.wsdl");

net/example/resources パッケージの jar 内に保存されているリソースを指すことに問題はないと確信しており、jar 自体は期待どおりに構築されています。ただし、サービスは読み込まれません...具体的には、ApplicationService.getPort(); を呼び出すと NullPointerException が発生します。

これは可能ですか?それともただのガチョウ追跡?

4

13 に答える 13

50

はい、WS-A 関連クラスである javax.xml.ws.EndpointReference を介してクライアントを作成するときに行ったので、これは間違いなく可能です。WSDL へのクラスパス参照を WS-A EndPointReference に追加し、JAX-WS の Metro 実装がそれを正常にロードしました。WSDL を WS-A EndPointReference からロードする場合でも、ファイルまたは http URL からロードする場合でも、JAX-WS 実装では、URL を解決するだけなので、同じ WSDL 解析コードを使用する必要があります。

おそらく、次のようなことを行うのが最善の方法です。

URL wsdlUrl = MyClass.class.getResource(
            "/class/path/to/wsdl/yourWSDL.wsdl");

Service yourService= Service.create(
            wsdlUrl,
            ...);

... は、WSDL 内の WSDL サービスの QName を表します。ここで覚えておくべき重要なことは、WSDL が完全で有効である必要があるということです。これは、WSDL が XSD ファイルまたは他の WSDL をインポートする場合、URL が正しい必要があることを意味します。インポートした WSDL および XSD を WSDL ファイルと同じ JAR に含めた場合は、インポートに相対 URL を使用し、すべてのインポートを同じ JAR ファイルに保持する必要があります。JAR URL ハンドラーは、相対 URL をクラスパスに対する相対としてではなく、JAR ファイル内の相対として処理するため、カスタム URL ハンドラーと独自のプレフィックスを実装しない限り、JAR 間で実行される WSDL にインポートを含めることはできません。インポートのクラスパスベースの解決。WSDL が外部リソースをインポートする場合、それは問題ありません。ただし、それらのリソースが移動した場合は、メンテナンスの問題にサインアップしています。クラスパスから WSDL の静的コピーを使用することでさえ、WSDL、Web サービス、および JAX-WS の精神に反しますが、必要な場合があります。

最後に、静的 WSDL を埋め込む場合は、少なくともサービス エンドポイントをテストと展開の目的で構成可能にすることをお勧めします。Web サービス クライアントのエンドポイントを再構成するコードは次のとおりです。

  YourClientInterface client = yourService.getPort(
            new QName("...", "..."),
            YourClientInterface.class);
  BindingProvider bp = (BindingProvider) client;
  bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                "http://localhost:8080/yourServiceEndpoint");
于 2009-05-14T14:14:05.930 に答える
17

少なくとも最近の JAX-WSでは、WSDL を JAR に入れ、wsimportwsdlLocationJARの WSDL の相対リソース パスに設定する場合、スキーマ カタログやプログラムによる wsdl の場所の設定を行う必要はありません。つまり、JAX-WS は Java のビルトインを使用Class.getResourceして WSDL をロードします。

Maven を使用している場合は、次のようになります。

  <plugin>
    <groupId>org.jvnet.jax-ws-commons</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.3</version>
    <executions>
      <execution>
        <goals>
          <goal>wsimport</goal>
        </goals>
        <!-- Following configuration will invoke wsimport once for each wsdl. -->
        <configuration>
            <!--- VERY IMPORTANT THAT THE PATH START WITH '/' -->
    <wsdlLocation>/com/adamgent/ws/blah.wsdl</wsdlLocation>
    <wsdlDirectory>${basedir}/src/main/resources/com/adamgent/ws</wsdlDirectory>
    <wsdlFiles><wsdlFile>blah.wsdl</wsdlFile></wsdlFiles>
       </configuration>
      </execution>
    </executions>
  </plugin>

上記の例では、Maven プロジェクト レイアウトを使用して WSDL をここに配置しますsrc/main/resources/com/adamgent/ws

次のように、WSDL が Maven の JAR に含まれていることを確認します。

<build>
      <resources>
        <resource>
          <directory>src/main/resources</directory>
        </resource>
      </resources> ....

これで、wsimport によって生成されたコードと WSDL が自己完結型の JAR に含まれます。このサービスを使用するには、WSDL の場所を設定する必要はなく、次のように簡単です。

BlahService myService = new BlayService_Service().getBlahServicePort();

これを ANT の wsimport にマッピングするのは簡単です。

于 2013-08-19T22:01:29.257 に答える
6

少し遅れたかもしれませんが、この問題を解決するために機能する非常に単純な解決策を見つけましたが、これには Service クラスの生成コードの変更が含まれていました。

Service クラスの次の行の場合

baseUrl = net.example.ApplicationService.class.getResource(".");

に変更されます

baseUrl = net.example.ApplicationService.class.getResource("");

JAR 内にパックされた WSDL でも問題なく動作します。どちらの場合でも getResource() の正確な想定動作についてはわかりませんが、これまでのところ、複数の OS と Java バージョンでこのアプローチに問題はありませんでした。

于 2009-11-20T14:40:29.240 に答える
4

クラスパスに「.」がある場合 その中で Class.getResource(".") は、Java コマンドを実行したディレクトリの URL を返します。それ以外の場合は、null が返されます。それに応じて wsdllocation を調整します。

于 2009-05-06T17:40:14.750 に答える
3

別の答えは、

new Service(wsdllocation, servicename );

サービス オブジェクトを取得します。

これが私が問題を解決した方法です。

于 2010-01-08T07:11:06.753 に答える
2

私は同じ問題に出くわしました。JAXWS生成クライアントコードはこのMyService.class.getResource(".")トリックを使用してwsdlファイルをロードします...しかし、テスト後、これはクラスファイルがファイルシステムのディレクトリにある場合にのみ機能するようです。クラスファイルがJARにある場合、この呼び出しはURLに対してnullを返します。

次のようにURLを作成すると、JDKのバグのように聞こえます。

final URL url = new URL( MyService.class.getResource( MyService.class.getSimpleName() + ".class"), "myservice.wsdl");

次に、クラスとwsdlがjarにバンドルされている場合にも機能します。

私はほとんどの人が実際に瓶に束ねると思います!

于 2009-06-09T14:35:05.967 に答える
2

ここにクライアントjarを構築する前に、WSDLの場所を置き換えました。

  1. WSDL をクラス ディレクトリにコピーします。
  2. クラスパスを使用して WSDL を参照する Service クラスを置き換えます。
  3. クライアント スタブを構築します。
  4. スタブを瓶詰めします。
<copy todir="@{dest-dir}/@{dir-package}" verbose="@{verbose}">
  <fileset dir="@{dir-wsdl}" includes="*.wsdl,*.xsd" />
</copy>
<echo message="Replacing Service to point to correct WSDL path..." />
<replaceregexp match="new URL(.*)" replace='Class.class.getResource("@{name-wsdl}");' flags="gm">
  <fileset dir="@{source-dest-dir}">
    <include name="@{dir-package}/*Service.java" />
  </fileset>
</replaceregexp>
<replaceregexp match="catch (.*)" replace='catch (Exception ex) {' flags="gm">
  <fileset dir="@{source-dest-dir}">
    <include name="@{dir-package}/*Service.java" />
  </fileset>
</replaceregexp>
于 2011-06-24T09:22:00.353 に答える
1

これが私のハックの回避策です。

jarからWSDLを解凍し、jarの近くのファイルに書き込みます。

File wsdl = new File("../lib/service.wsdl");
InputStream source = getClass().getResource("resources/service.wsdl").openStream();
FileOutputStream out = new FileOutputStream(wsdl);

byte[] buffer = new byte[512];
int read;
while((read = source.read(buffer)) >= 0) {
    out.write(buffer, 0, read);
}

次に、サービスクラスをにポイントしますfile:../lib/service.wsdl

これは機能しますが、誰かが私にもっとエレガントな解決策を見せてくれれば幸いです。

于 2009-04-19T15:08:31.367 に答える
0

私の解決策は、生成されたサービスを変更することでした。ヘッダー アノテーションのwsdlLocationを変更する必要があり、インスタンス ブロックは次のようになります。

    static {
    URL url = null;
    url = com.ups.wsdl.xoltws.ship.v1.ShipService.class.getResource("Ship.wsdl");
    SHIPSERVICE_WSDL_LOCATION = url;
    }

ShipService クラスの隣の bin ディレクトリに wsdl ファイルを配置します。

于 2014-05-22T21:21:21.053 に答える