[解決済み] CXFまたはJAX-WSで生成されたWebサービスクライアントで、WSDLの場所を指定する必要がないようにするにはどうすればよいですか。
質問内容
CXFからwsdl2java(wsimportに似たものを生成する)を使って、maven経由でWebサービスクライアントを生成すると、私のサービスは次のようなコードで始まります。
@WebServiceClient(name = "StatusManagement",
wsdlLocation = "c:/some_absolute_path_to_a_wsdl_file.wsdl",
targetNamespace = "http://tempuri.org/")
public class StatusManagement extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
static {
URL url = null;
try {
url = new URL("c:/some_absolute_path_to_a_wsdl_file.wsdl");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from c:/some_absolute_path_to_a_wsdl_file.wsdl");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
ハードコードされた絶対パスは本当に最悪です。生成されたクラスは、私以外のコンピュータでは動作しません。
最初のアイデアは、WSDLファイル(とそれがインポートするすべて、他のWSDLとXSD)をjarファイルのどこかに置き、それをクラスパスすることです。しかし、私たちはこれを避けたい。CXFとJAXBはWSDLとXSDに基づいてすべてのものを生成しているので、実行時にWSDLを知る必要はないと考えているのだ。
wsdlLocation属性はWSDLの場所を上書きするためのもので、(少なくとも私はどこかで読んだのですが)そのデフォルト値は""です。maven を使用しているため、WSDL を記述するために
<wsdlLocation></wsdlLocation>
CXFの設定内で、ソース・ジェネレーターがwsdlLocationを空白にするように強制しようとします。しかし、これは単にXMLタグが空であるため無視されるだけです。私たちは、本当に醜い恥ずべきハックを行いました。
<wsdlLocation>" + "</wsdlLocation>
.
これは他の箇所も変わります。
@WebServiceClient(name = "StatusManagement",
wsdlLocation = "" + "",
targetNamespace = "http://tempuri.org/")
public class StatusManagement extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
static {
URL url = null;
try {
url = new URL("" + "");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from " + "");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
そこで質問なのですが
-
すべてのクラスがCXFとJAXBで生成されたとしても、WSDLの場所は本当に必要なのでしょうか?もしそうなら、なぜですか?
-
WSDLの場所が本当に必要でない場合、CXFがそれを生成しないようにし、完全にそれを回避する適切でクリーンな方法は何ですか?
-
そのハックによって、どんな悪い副作用があるのでしょうか?私たちはまだそれがどうなるかテストすることができないので、誰かが事前に言ってくれると助かるのですが。
解決方法は?
今日、ようやくこの問題の正解がわかりました。
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${project.basedir}/src/main/resources/wsdl/FooService.wsdl</wsdl>
<wsdlLocation>classpath:wsdl/FooService.wsdl</wsdlLocation>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
の値に接頭辞をつけていることに注目してください。
wsdlLocation
で
classpath:
. これはプラグインに、wsdlが絶対パスではなくクラスパス上にあることを伝えます。そうすると、次のようなコードが生成されます。
@WebServiceClient(name = "FooService",
wsdlLocation = "classpath:wsdl/FooService.wsdl",
targetNamespace = "http://org/example/foo")
public class Foo_Service extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://org/example/foo", "Foo");
public final static QName FooSOAPOverHTTP = new QName("http://org/example/foo", "Foo_SOAPOverHTTP");
static {
URL url = Foo_Service.class.getClassLoader().getResource("wsdl/FooService.wsdl");
if (url == null) {
java.util.logging.Logger.getLogger(Foo_Service.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "classpath:wsdl/FooService.wsdl");
}
WSDL_LOCATION = url;
}
バージョン 2.4.1 以降の cxf-codegen-plugin でしか動作しないことに注意してください。
関連
-
javaで非静的な解を静的な参照にすることができない
-
javaの模造品QQ WeChatのチャットルーム
-
スキャナは、タイプに解決することはできません最もルーキー初心者の質問
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
eclipse の実行時に java 仮想マシンが見つからなかった
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
Spring BootのテストメソッドFailed to load ApplicationContextの問題を解決する
-
HttpClientがGZIP形式でない場合の対処法
-
起動時にEclipseエラーが発生しました。起動中に内部エラーが発生しました。java.lang.NullPoin: "Javaツーリングの初期化 "中に内部エラーが発生しました。
-
JSPで「リストが型解決できない!」の解決方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
java の例外が発生しました java
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
プロジェクトの依存関係を解決できなかった 解決
-
Eclipseでプロジェクトエクスプローラービューとパッケージエクスプローラービューを使う
-
Spring boot runs with Error creating bean with name 'entityManagerFactory' defined in class path resource
-
が 'X-Frame-Options' を 'deny' に設定しているため、フレーム内にある。
-
org.glassfish.jersey.servlet.ServletContainer
-
java.lang.NoClassDefFoundError: org.apache.jasper.el.ELContextImpl クラスを初期化できませんでした。
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について