apache cxf无法发送消息和读取超时

时间:2013-01-31 10:35:10

标签: java apache timeout 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发送肥皂请求后发生。我正在使用apache cxf。我完全确定ws已启动并运行,因为在超时发生之前,客户端将再发送2个请求。超时发生在第三个soap请求中。

4 个答案:

答案 0 :(得分:17)

我的webservice客户端也遇到过这个错误。对我有用的解决方案是在CXF配置文件(cxf.xml)中配置http客户端。

Apache CXF document中所述:

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>

答案 1 :(得分:13)

错误消息表示您的Web服务客户端尝试通过网络从远程Web服务接收数据,但在特定时间段内未收到任何数据,因此Web服务客户端停止等待数据接收。

可能的原因之一可能是timeout属性太低。默认为cxf默认值分别为30000和60000 ms。这些可以根据您创建客户端的方式进行更改。

如果您使用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.../>配置。

答案 2 :(得分:2)

配置超时的另一个方法(以编程方式):

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);
}

答案 3 :(得分:0)

您可能希望从Apache CXF src更改receiveTimeout设置,并替换服务器中现有的cxf-rt-transports-http-version.jar。

简要说明:(听取了Wildfly 8.2/undertow read time out

的说明
  1. 从apache下载CXF2.7.16 src
  2. 将maven / bin添加到PATH
  3. 导出MAVEN_OPTS = -Xmx512m以修复permgen错误
  4. 打开./rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd并将ReceiveTimeout从60000更改为例如所需的任何内容。 600000(10分钟)
  5. 运行mvn -Pfastinstall
  6. 从./rt/transports/http/target文件夹中获取“patched”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。
  8. 这应解决由服务器中使用的基础Apache CXF引起的SocketTimeoutException。