web-dev-qa-db-ja.com

apache cxfはメッセージを送信できず、タイムアウトを読み取ることができませんでした

原因は何ですか:

org.Apache.cxf.interceptor.Fault: Could not send Message.

Caused by: Java.net.SocketTimeoutException: SocketTimeoutException invoking https://xxx.xxx.xxx.xxx:8443/services/test: Read timed out

通常、wsにsoapリクエストを送信した後に発生します。 Apache cxfを使用しています。タイムアウトが発生する前にクライアントがさらに2つのリクエストを送信するため、wsが稼働していることを完全に確信しています。 3番目のsoap要求でタイムアウトが発生します。

15
irumi

Webサービスクライアントでもこのエラーが発生しました。私のために働いた解決策は、CXF構成ファイル(cxf.xml)でhttpクライアントを構成することです。

Apache CXFドキュメント に記載されているとおり:

1. http-conduit名前空間とxsdを追加します。

<beans ...
       xmlns:http-conf="http://cxf.Apache.org/transports/http/configuration
       ...
       xsi:schemaLocation="...
           http://cxf.Apache.org/transports/http/configuration
           http://cxf.Apache.org/schemas/configuration/http-conf.xsd
       ...">

2. http-conduitタグ/要素を追加し、RecieveTimeout/ConnectionTimeoutを180000msに設定します。

<http-conf:conduit name="*.http-conduit">
      <http-conf:client 
                      ConnectionTimeout="300000"
                      ReceiveTimeout="300000"/>       
</http-conf:conduit>

このエラーメッセージは、Webサービスクライアントがネットワーク経由でリモートWebサービスからデータを受信しようとしていたが、特定の期間データを受信しなかったため、Webサービスクライアントがデータの受信を待機しなくなったことを意味します。

考えられる原因の1つは、timeoutプロパティが低すぎることです。 cxfのデフォルト値はそれぞれ30000および60000ミリ秒です。これらは、クライアントの作成方法に応じて変更できます。

Javaコードを使用してクライアントを作成している場合は、次を使用できます。

//1 minute for connection
((BindingProvider) wsPort).getRequestContext().put("com.Sun.xml.ws.connect.timeout", 1 * 60 * 1000); 

//3 minutes for request
((BindingProvider) wsPort).getRequestContext().put("com.Sun.xml.ws.request.timeout", 3 * 60 * 1000); 

Springを使用している場合、次のようなマップを使用できます。

<util:map id="jaxwsProperties">
    <entry key="com.Sun.xml.internal.ws.request.timeout">
        <value type="Java.lang.Integer">120000</value>
    </entry>
    <entry key="com.Sun.xml.internal.ws.connect.timeout">
        <value type="Java.lang.Integer">60000</value>
    </entry>
</util:map>

次に、そのマップを<jaxws:client.../>設定。

13

(プログラムで)タイムアウトを設定する別のアプローチ:

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
Object serviceClass = factory.create();
defineTimeouts(serviceClass);

static void defineTimeouts(Object serviceClass) {
    Client cxfClient = ClientProxy.getClient(serviceClass);
    HTTPConduit httpConduit = (HTTPConduit) cxfClient.getConduit();

    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
    httpClientPolicy.setConnectionTimeout(DEFAULT_CLIENT_CONNECTION_TIMEOUT);
    httpClientPolicy.setReceiveTimeout(DEFAULT_CLIENT_RECEIVE_TIMEOUT);
    httpConduit.setClient(httpClientPolicy);
}
2
Bob Rivers

Apache CXF srcのreceiveTimeout設定を変更し、サーバーの既存のcxf-rt-transports-http-version.jarを置き換えることができます。

簡単な説明:( Wildfly 8.2/undertow read time out )から指示を入手してください)

  1. ApacheからCXF2.7.16 srcをダウンロードします
  2. PATHにmaven/binを追加します
  3. Permgenエラーを修正するためにMAVEN_OPTS = -Xmx512mをエクスポートします
  4. ./rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsdを開き、ReceiveTimeoutを60000から必要なものに変更します。 600000(10分)
  5. Mvn -Pfastinstallを実行します
  6. ./rt/transports/http/targetフォルダーから「パッチを適用した」cxf-rt-transports-http-2.7.16.jarを取得します
  7. サーバーのcxf-rt-transports-http-2.7.16.jarを置き換えます。たとえば、wildfly8.2では、。// modules/system/layers/base/org/Apache/cxf/impl/mainフォルダーにあり、同じフォルダー内のmodule.xmlを更新して、このパッチを適用したcxf-rtを使用することを忘れないでください-transports-http-2.7.16.jar。

これにより、サーバーで使用される基礎となるApache CXFが原因のSocketTimeoutExceptionが解決されるはずです。

0
Henry Neo