JAX-WS Webサービスクライアントのタイムアウトを設定するにはどうすればよいですか?


93

JAXWS-RI 2.1を使用して、WSDLに基づいてWebサービスのインターフェースを作成しました。Webサービスと問題なく対話できますが、Webサービスにリクエストを送信するためのタイムアウトを指定できませんでした。何らかの理由でクライアントが応答しない場合、クライアントは永久に回転しているように見えます。

周りを探して、私はおそらく次のようなことをしようとする必要があることを明らかにしました:

((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.ws.request.timeout", 10000);
((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.ws.connect.timeout", 10000);

また、使用しているJAXWS-RIのバージョンによっては、代わりにこれらのプロパティを設定する必要がある場合があることも発見しました。

((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 10000);
((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 10000);

私が抱えている問題は、上記のどちらが正しいかに関係なく、どここれを実行できるのかわからないということです。私が持っているのは、ServiceWebサービスへの自動生成されたインターフェイスを実装するサブクラスだけです。これがインスタンス化されている時点で、WSDLが応答しない場合、すでにプロパティを設定するには遅すぎます。

MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
soap.sendRequestToMyWebService();

誰かが私を正しい方向に向けることができますか?


5
答えはないと思いますが、あなたの質問が私の問題の解決に役立ちました。com.sun.xml.ws.request.timeoutプロパティについては知っていましたが、com.sun.xml.internal.ws.request.timeoutプロパティについては知りませんでした。
Ron Tuffin

回答:


89

私はこれが古いことを知っており、他の場所で回答されていますが、うまくいけばこれはこれを閉じます。WSDLを動的にダウンロードする理由はわかりませんが、システムプロパティは次のとおりです。

sun.net.client.defaultConnectTimeout (default: -1 (forever))
sun.net.client.defaultReadTimeout (default: -1 (forever))

JAX-WSが使用するHttpURLConnectionを使用して、すべての読み取りと接続に適用する必要があります。WSDLをリモートの場所から取得している場合は、これで問題が解決するはずですが、ローカルディスク上のファイルの方が良いでしょう。

次に、特定のサービスのタイムアウトを設定する場合は、プロキシを作成したら、それをBindingProvider(既に知っている)にキャストし、リクエストコンテキストを取得してプロパティを設定する必要があります。オンラインのJAX-WSドキュメントは間違っています。これらは正しいプロパティ名です(まあ、私にとってはうまくいきます)。

MyInterface myInterface = new MyInterfaceService().getMyInterfaceSOAP();
Map<String, Object> requestContext = ((BindingProvider)myInterface).getRequestContext();
requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT, 3000); // Timeout in millis
requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT, 1000); // Timeout in millis
myInterface.callMyRemoteMethodWith(myParameter);

もちろん、これは恐ろしい方法です。必要なタイムアウトを注入できるこれらのバインディングプロバイダーを作成するための素晴らしいファクトリを作成します。


10
REQUEST_TIMEOUT / CONNECT_TIMEOUTプロパティは実際にはSUN内部クラスcom.sun.xml.internal.ws.developer.JAXWSPropertiesから継承され、(少なくとも32ビットLinuxでは)javac 1.6.0_27およびjavac 1.7.0_03が失敗することに注意してください。このコードをコンパイルします(bugs.sun.com/view_bug.do?bug_id=6544224と同様)... -XDignore.symbol.fileをjavacに渡して機能させる必要があります。
JavaGuy、2012年

何がうまくいかないのですか?これを再確認したところ、うまくいきました。
12

私がJAX-WS RI 2.2.8とJDK 1.7でこれを使用したことを確認したところ、問題なく動作しました。ありがとうございました!
bconneen 2014年

完全修飾名に「内部」が含まれるクラスとパラメーターは使用しないでください。ベンダーに依存するため、さまざまなJDK実装間で移植できません。たとえば、jax-wsパラメータの場合、対応する非内部プロパティがcom.sun.xml.ws.client.BindingProviderPropertiesクラスに存在します。
ポラレット2015

1
@ Matt1776はい、もちろんありません。JAX-WSはAPI仕様ですが、ライブラリの実装が必要です。この場合は、JDKの一部ではないjaxws-ri.jarまたはjaxws-rt.jarです。ダウンロードしてptojectに追加するだけで、これらのプロパティを利用できるようになります。
ポラレット

38

JAX-WSのJBoss実装を使用しているためか、受け入れられた回答のプロパティが機能しませんでした。

別のプロパティセット(JBoss JAX-WSユーザーガイドにあります)を使用すると機能します。

//Set timeout until a connection is established
((BindingProvider)port).getRequestContext().put("javax.xml.ws.client.connectionTimeout", "6000");

//Set timeout until the response is received
((BindingProvider) port).getRequestContext().put("javax.xml.ws.client.receiveTimeout", "1000");

2
私はJBossを使用していませんが、このコメントのプロパティのみが機能し、他には何も機能しませんでした。
PaulP

2
プロパティ名はJAX-WS実装によって異なります。リストはここにあります:java.net/jira/browse/JAX_WS-1166
fabstab

3
java.netリンクが壊れています。github.com/javaee/metro-jax-ws/issues/1166
trunkc

12

これが私の実用的な解決策です:

// --------------------------
// SOAP Message creation
// --------------------------
SOAPMessage sm = MessageFactory.newInstance().createMessage();
sm.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
sm.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");

SOAPPart sp = sm.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
se.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/");
se.setAttribute("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/");
se.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
se.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

SOAPBody sb = sm.getSOAPBody();
// 
// Add all input fields here ...
// 

SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
// -----------------------------------
// URL creation with TimeOut connexion
// -----------------------------------
URL endpoint = new URL(null,
                      "http://myDomain/myWebService.php",
                    new URLStreamHandler() { // Anonymous (inline) class
                    @Override
                    protected URLConnection openConnection(URL url) throws IOException {
                    URL clone_url = new URL(url.toString());
                    HttpURLConnection clone_urlconnection = (HttpURLConnection) clone_url.openConnection();
                    // TimeOut settings
                    clone_urlconnection.setConnectTimeout(10000);
                    clone_urlconnection.setReadTimeout(10000);
                    return(clone_urlconnection);
                    }
                });


try {
    // -----------------
    // Send SOAP message
    // -----------------
    SOAPMessage retour = connection.call(sm, endpoint);
}
catch(Exception e) {
    if ((e instanceof com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl) && (e.getCause()!=null) && (e.getCause().getCause()!=null) && (e.getCause().getCause().getCause()!=null)) {
        System.err.println("[" + e + "] Error sending SOAP message. Initial error cause = " + e.getCause().getCause().getCause());
    }
    else {
        System.err.println("[" + e + "] Error sending SOAP message.");

    }
}

3
これらの構成は「javax.xml.ws.client.connectionTimeout」および「javax.xml.ws.client.receiveTimeout」と同等ですか?
Jose Tepedino、2018年

11
ProxyWs proxy = (ProxyWs) factory.create();
Client client = ClientProxy.getClient(proxy);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(0);
httpClientPolicy.setReceiveTimeout(0);
http.setClient(httpClientPolicy);

これでうまくいきました。


ありがとう!私にとっても、それは本当に簡単な方法です
kosm 14

4
これはApache CXFクラスを使用しますが、これを回答に追加するのが最善の場合があります。CXF jarにそれらが含まれているリンクも非常に役立ちます。
JBert

@JBert同意する。私はこの数年前に答えたので、思い出せません。回答を自由に編集してください。
Daniel Kaplan 2014

8

JDK6でJAX-WSを使用している場合は、次のプロパティを使用します。

com.sun.xml.internal.ws.connect.timeout  
com.sun.xml.internal.ws.request.timeout

System.setProperty( "com.sun.xml.internal.ws.connect.timeout"、 "300"); System.setProperty( "com.sun.xml.internal.ws.request.timeout"、 "300")は私のために働いた。
2787184

2
一部のコンテキストでは、実行時に使用されるJAXWSバージョン(内部またはスタンドアロン)がプログラミング時にわかりません。このタイムアウト機能を除いて、2つは完全に互換性があります。キーは異なります(com.sun.xml.internal.ws.connect.timeoutvs com.sun.xml.ws.connect.timeout)また、それらを定義するクラス(またはインターフェース)(com.sun.xml.internal.ws.developer.JAXWSProperties/ com.sun.xml.internal.ws.client.BindingProviderPropertiesvs com.sun.xml.ws.developer.JAXWSProperties/ com.sun.xml.ws.client.BindingProviderProperties)。私の最良のアイデアは、リテラル値をキーとして使用して両方を設定することです。
Lorinczy Zsigmond 2018

5

appserverがWebLogicの場合(私にとっては10.3.6でした)、タイムアウトを担当するプロパティは次のとおりです。

com.sun.xml.ws.connect.timeout 
com.sun.xml.ws.request.timeout

3

これがあなたの状況で役立つかどうかわかりません...

SOAPオブジェクトをBindingProviderとしてキャストできますか?

MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
// set timeouts here
((BindingProvider)soap).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 10000);
    soap.sendRequestToMyWebService();

一方、MyWebServiceオブジェクトの初期化でタイムアウトを設定する場合、これは役に立ちません。

これは、個々のWebService呼び出しをタイムアウトさせたい場合に役立ちました。


2

SEIをインスタンス化するときにリモートWSDLの取得が遅くならないようにする最も簡単な方法は、実行時にリモートサービスエンドポイントからWSDLを取得しないことです。

つまり、サービスプロバイダーが影響を与える変更を行うたびにローカルのWSDLコピーを更新する必要がありますが、サービスプロバイダーが影響を与える変更を行うたびにローカルコピーを更新する必要があります。

クライアントスタブを生成するとき、クラスパス上の所定の場所からWSDLを読み取るようにSEIに注釈を付けるようにJAX-WSランタイムに指示します。デフォルトでは、場所はService SEIのパッケージの場所を基準にしています。


<wsimport
    sourcedestdir="${dao.helter.dir}/build/generated"
    destdir="${dao.helter.dir}/build/bin/generated"
    wsdl="${dao.helter.dir}/src/resources/schema/helter/helterHttpServices.wsdl"
    wsdlLocation="./wsdl/helterHttpServices.wsdl"
    package="com.helter.esp.dao.helter.jaxws"
    >
    <binding dir="${dao.helter.dir}/src/resources/schema/helter" includes="*.xsd"/>
</wsimport>
<copy todir="${dao.helter.dir}/build/bin/generated/com/helter/esp/dao/helter/jaxws/wsdl">
    <fileset dir="${dao.helter.dir}/src/resources/schema/helter" includes="*" />
</copy>

wsldLocation属性は、SEIにWSDLがどこにあるかを伝え、コピーはwsdl(およびサポートするxsdなど)が正しい場所にあることを確認します。

場所はSEIのパッケージの場所を基準にしているため、wsdlという新しいサブパッケージ(ディレクトリ)を作成し、そこにすべてのwsdlアーティファクトをコピーします。

この時点で行う必要があるのは、クライアントスタブアーティファクトjarファイルを作成するときに、すべての* .classに加えてすべての* .wsdl、*。xsdを含めることです。

(好奇心が強い場合のために、@ webserviceClientアノテーションは、このwsdlの場所が実際にJavaコードで設定されている場所です

@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.