問題は、提供されたファイルからWebサービスクライアントを構築する必要があることです。このファイルをローカルファイルシステムに保存しました。WSDLファイルを正しいファイルシステムフォルダーに保持している間は、すべて問題ありません。サーバーにデプロイするか、ファイルシステムフォルダーからWSDLを削除すると、プロキシがWSDLを見つけられず、エラーが発生します。ウェブを検索しましたが、次の投稿を見つけましたが、機能させることができませんでした:
JAX-WS jarからWSDLを読み込んでいます
http://www.Java.net/forum/topic/glassfish/metro-and-jaxb/client-jar-cant-find-local-wsdl-
http://blog.vinodsingh.com/2008/12/locally-packaged-wsdl.html
NetBeans 6.1を使用しています(これは、この新しいWebサービスクライアントで更新する必要があるレガシーアプリケーションです)。以下はJAX-WSプロキシクラスです。
@WebServiceClient(name = "SOAService", targetNamespace = "http://soaservice.eci.ibm.com/", wsdlLocation = "file:/C:/local/path/to/wsdl/SOAService.wsdl")
public class SOAService
extends Service
{
private final static URL SOASERVICE_WSDL_LOCATION;
private final static Logger logger = Logger.getLogger(com.ibm.eci.soaservice.SOAService.class.getName());
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
public SOAService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SOAService() {
super(SOASERVICE_WSDL_LOCATION, new QName("http://soaservice.eci.ibm.com/", "SOAService"));
}
/**
* @return
* returns SOAServiceSoap
*/
@WebEndpoint(name = "SOAServiceSOAP")
public SOAServiceSoap getSOAServiceSOAP() {
return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class);
}
/**
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns SOAServiceSoap
*/
@WebEndpoint(name = "SOAServiceSOAP")
public SOAServiceSoap getSOAServiceSOAP(WebServiceFeature... features) {
return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class, features);
}
}
これはプロキシを使用するための私のコードです:
WebServiceClient annotation = SOAService.class.getAnnotation(WebServiceClient.class);
// trying to replicate proxy settings
URL baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource("");//note : proxy uses "."
URL url = new URL(baseUrl, "/WEB-INF/wsdl/client/SOAService.wsdl");
//URL wsdlUrl = this.getClass().getResource("/META-INF/wsdl/SOAService.wsdl");
SOAService serviceObj = new SOAService(url, new QName(annotation.targetNamespace(), annotation.name()));
proxy = serviceObj.getSOAServiceSOAP();
/* baseUrl;
//classes\com\ibm\eci\soaservice
//URL url = new URL(baseUrl, "../../../../wsdl/SOAService.wsdl");
proxy = new SOAService().getSOAServiceSOAP();*/
//updating service endpoint
Map<String, Object> ctxt = ((BindingProvider)proxy ).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WebServiceUrl);
NetBeansはWSDLのコピーをweb-inf/wsdl/client/SOAServiceに置くため、META-INFに追加したくないも。サービスクラスはWEB-INF/classes/com/ibm/eci/soaservice /にあり、baseurl変数にはファイルシステムのフルパス(c:\ path\to\the \プロジェクト...\soaservice)。上記のコードはエラーを発生させます:
javax.xml.ws.WebServiceException:ファイル:/WEB-INF/wsdl/client/SOAService.wsdlでWSDLにアクセスできませんでした。失敗しました:\ WEB-INF\wsdl\client\SOAService.wsdl(パスが見つかりません)
それでは、まず、プロキシクラスのwsdllocationを更新する必要がありますか?次に、WEB-INF/classes/com/ibm/eci/soaserviceのSOAServiceクラスに\ WEB-INF\wsdl\client\SOAService.wsdlのWSDLを検索するように指示するにはどうすればよいですか?
編集:この他のリンクを見つけました- http://jianmingli.com/wp/?cat=41 =、WSDLをクラスパスに入れることを言います。私は尋ねることを恥ずかしく思います:Webアプリケーションのクラスパスにどのように入れるのですか?
最適なオプションは、jax-ws-catalog.xmlを使用することです
ローカルのWSDLファイルをコンパイルするとき、WSDLの場所をオーバーライドし、次のようなものに設定します
http://localhost/wsdl/SOAService.wsdl
これはURIであり、URLではないことを心配しないでください。つまり、そのアドレスでWSDLを使用可能にする必要はありません。
これを行うには、wsdllocationオプションをwsdl to Javaコンパイラーに渡します。
そうすると、プロキシコードが
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
に
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "http://localhost/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'http://localhost/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
URLコンストラクターでfile://がhttp://に変更されていることに注意してください。
現在、jax-ws-catalog.xmlに含まれています。 jax-ws-catalog.xmlがない場合、jax-wsは実際に場所からWSDLをロードしようとします
http://localhost/wsdl/SOAService.wsdl
ただし、jax-ws-catalog.xmlを使用すると、WSDLにアクセスしようとするたびに、jax-wsをローカルにパッケージ化されたWSDLにリダイレクトできます@
http://localhost/wsdl/SOAService.wsdl
これがjax-ws-catalog.xmlです
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
<system systemId="http://localhost/wsdl/SOAService.wsdl"
uri="wsdl/SOAService.wsdl"/>
</catalog>
あなたがやっていることは、いつでもWSDLをロードする必要があることをjax-wsに伝えることです
http://localhost/wsdl/SOAService.wsdl
ここで、wsdl/SOAService.wsdlとjax-ws-catalog.xmlをどこに配置する必要がありますか?それは百万ドルの質問ですね。
アプリケーションjarのMETA-INFディレクトリにあります。
こんな感じ
ABCD.jar | __ META-INF | __ jax-ws-catalog.xml | __ wsdl | __ SOAService.wsdl
このように、プロキシにアクセスするクライアントのURLをオーバーライドする必要さえありません。 WSDLはJAR内から取得されるため、コードにファイルシステムパスをハードコーディングする必要はありません。
Jax-ws-catalog.xmlの詳細 http://jax-ws.Java.net/nonav/2.1.2m1/docs/catalog-support.html
役立つことを願っています
成功したもう1つのアプローチは、wsimport(AntからAntタスクとして)を使用してWSクライアントプロキシコードを生成し、wsdlLocation属性を指定することです。
<wsimport debug="true" keep="true" verbose="false" target="2.1" sourcedestdir="${generated.client}" wsdl="${src}${wsdl.file}" wsdlLocation="${wsdl.file}">
</wsimport>
複数のWSDLを含むプロジェクトに対してこれを実行するため、スクリプトは$(wsdl.file}値を動的に解決します。この値は、JavaSourceの場所(または/ src、プロジェクトの設定方法によって異なります)ビルドプロセス中に、WSDLファイルとXSDファイルがこの場所にコピーされ、JARファイルにパッケージ化されます(上記のBhasakarが説明したソリューションと同様)。
MyApp.jar
|__META-INF
|__wsdl
|__YourWebServiceName.wsdl
|__YourWebServiceName_schema1.xsd
|__YourWebServiceName_schmea2.xsd
注:WSDLファイルが、http URLではなく、インポートされたXSDに対して相対的な参照を使用していることを確認してください。
<types>
<xsd:schema>
<xsd:import namespace="http://valueobject.common.services.xyz.com/" schemaLocation="YourWebService_schema1.xsd"/>
</xsd:schema>
<xsd:schema>
<xsd:import namespace="http://exceptions.util.xyz.com/" schemaLocation="YourWebService_schema2.xsd"/>
</xsd:schema>
</types>
generatedコードで、これを見つけます:
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2-b05-
* Generated source version: 2.1
*
*/
@WebServiceClient(name = "YourService", targetNamespace = "http://test.webservice.services.xyz.com/", wsdlLocation = "/META-INF/wsdl/YourService.wsdl")
public class YourService_Service
extends Service
{
private final static URL YOURWEBSERVICE_WSDL_LOCATION;
private final static WebServiceException YOURWEBSERVICE_EXCEPTION;
private final static QName YOURWEBSERVICE_QNAME = new QName("http://test.webservice.services.xyz.com/", "YourService");
static {
YOURWEBSERVICE_WSDL_LOCATION = com.xyz.services.webservice.test.YourService_Service.class.getResource("/META-INF/wsdl/YourService.wsdl");
WebServiceException e = null;
if (YOURWEBSERVICE_WSDL_LOCATION == null) {
e = new WebServiceException("Cannot find '/META-INF/wsdl/YourService.wsdl' wsdl. Place the resource correctly in the classpath.");
}
YOURWEBSERVICE_EXCEPTION = e;
}
public YourService_Service() {
super(__getWsdlLocation(), YOURWEBSERVICE_QNAME);
}
public YourService_Service(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
/**
*
* @return
* returns YourService
*/
@WebEndpoint(name = "YourServicePort")
public YourService getYourServicePort() {
return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class);
}
/**
*
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns YourService
*/
@WebEndpoint(name = "YourServicePort")
public YourService getYourServicePort(WebServiceFeature... features) {
return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class, features);
}
private static URL __getWsdlLocation() {
if (YOURWEBSERVICE_EXCEPTION!= null) {
throw YOURWEBSERVICE_EXCEPTION;
}
return YOURWEBSERVICE_WSDL_LOCATION;
}
}
おそらくこれも役立つかもしれません。 「カタログ」アプローチを使用しない別のアプローチです。
Bhaskar Karambelkarの回答に感謝します。詳細に説明し、私の問題を修正しました。しかし、私はまた、急いで修正する人のために、3つの簡単なステップで答えを言い直したいと思います
wsdlLocation= "http://localhost/wsdl/yourwsdlname.wsdl"
として作成します以下のように、META-INFの下にXMLファイルjax-ws-catalog.xmlを作成します
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system"> <system systemId="http://localhost/wsdl/yourwsdlname.wsdl" uri="wsdl/yourwsdlname.wsdl" /> </catalog>
次に、jarをパッケージ化します。ローカルディレクトリへの参照はもうありません。すべてがパッケージ化され、参照されます。
Springを使用している人は、classpath-protocolを使用してクラスパスリソースを簡単に参照できます。したがって、wsdlLocationの場合、これは次のようになります。
<wsdlLocation>classpath:META-INF/webservice.wsdl</wsdlLocation>
これは標準のJava動作ではないことに注意してください。参照: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html
exactここで説明したのと同じ問題がありました。上記の例に従って、WSDLファイルの場所を(Webサーバーの場合)変更するために何をしたとしても、サーバープロセスのソースツリーに埋め込まれた元の場所を引き続き参照していました。
MANYこれをデバッグしようとすると、例外が常にまったく同じ行からスローされていることに気付きました(私の場合は41)。最後に今朝、ソースコードをトレードパートナーに送信することで、少なくともコードがどのように見えるかを理解できるようにしましたが、独自のコードを作成することもできました。私のショックおよびhorrorに、クライアントソースツリー内で.Javaファイルと混合したクラスファイルの束を見つけました。なんて奇妙な!!これらはJAX-WSクライアントビルダーツールの副産物であると思われます。
これらの愚かな.classファイルを圧縮し、クライアントコードの完全なクリーンアップと再構築を実行すると、すべてが完全に機能します!!すごい!!
YMMV、アンドリュー