下面我将详细讲解如何在这两种场景下设置超时,并以主流的 JAX-WS (Java API for XML Web Services) 和 Apache CXF 为例进行说明。

客户端超时设置 (Client-side Timeout)
客户端超时指的是,当客户端调用一个 WebService 时,如果在指定的时间内没有收到服务器的响应,就认为请求失败并抛出超时异常。
JAX-WS 客户端超时设置
JAX-WS 客户端通常通过 BindingProvider 接口来配置连接和读取超时。
核心概念:
javax.xml.ws.BindingProvider: 所有 JAX-WS 客户端端口(Port)都实现了这个接口。javax.xml.ws.WebServiceFeature: 用于配置 WebService 的特性,HTTPClientPolicy就是一个用于配置 HTTP 客户端行为的特性,它包含了超时设置。
示例代码:

假设我们有一个客户端生成的 MyService 类。
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.soap.SOAPBinding;
import com.sun.xml.ws.client.BindingProviderProperties; // 注意:这是 Sun/Oracle 的特定 API
import com.sun.xml.ws.developer.JAXWSProperties; // 更通用的 API
public class JaxwsClientTimeoutExample {
public static void main(String[] args) {
// 1. 创建 WebService 客户端
MyService service = new MyService();
MyServicePortType port = service.getMyServicePort();
// 2. 获取 BindingProvider 实例
BindingProvider bindingProvider = (BindingProvider) port;
// 3. 设置超时 (两种方式,推荐使用第二种更标准的方式)
// 方式一:使用 Sun/Oracle 特定的属性 (简单直接,但可移植性稍差)
bindingProvider.getRequestContext().put(
BindingProviderProperties.CONNECT_TIMEOUT, 5000); // 5秒连接超时
bindingProvider.getRequestContext().put(
BindingProviderProperties.REQUEST_TIMEOUT, 10000); // 10秒读取超时
// 方式二:使用标准的 HTTPClientPolicy (更推荐,可移植性好)
// 首先获取或创建 SOAPBinding
SOAPBinding binding = (SOAPBinding) bindingProvider.getBinding();
// 创建 HTTPClientPolicy
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(5000); // 5秒连接超时
httpClientPolicy.setReceiveTimeout(10000); // 10秒读取超时
// 将 policy 应用到 binding
binding.setOutboundAttachments(null); // 清除旧的附件策略
binding.setHandlerChain(null); // 清除旧的处理器链
binding.setFeature(new HTTPClientFeature(httpClientPolicy)); // 设置新的特性
// 4. 调用 WebService
try {
String result = port.someMethod("some data");
System.out.println("调用成功: " + result);
} catch (Exception e) {
System.err.println("调用失败: " + e.getMessage());
e.printStackTrace();
}
}
}
参数解释:
CONNECT_TIMEOUT/setConnectionTimeout(): 客户端与服务器建立 TCP 连接的超时时间(单位:毫秒),如果在这段时间内无法建立连接,则会抛出java.net.SocketTimeoutException。REQUEST_TIMEOUT/setReceiveTimeout(): 客户端从服务器接收响应数据的超时时间(单位:毫秒),如果在这段时间内没有完整地接收到响应数据,则会抛出java.net.SocketTimeoutException。
Apache CXF 客户端超时设置
Apache CXF 是一个功能强大的开源框架,它对超时的控制更加灵活和细致。
核心概念:

org.apache.cxf.configuration.jsse.TLSClientParameters: 用于配置 SSL/TLS 相关的超时。org.apache.cxf.frontend.ClientProxy: 用于获取客户端的底层配置对象。org.apache.cxf.transports.http.configuration.HTTPClientPolicy: CXF 中用于配置 HTTP 客户端的核心策略类。
示例代码:
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy.ConnectionTimeout;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy.ReceiveTimeout;
public class CxfClientTimeoutExample {
public static void main(String[] args) {
// 1. 创建 WebService 客户端 (假设使用 CXF 生成的客户端)
MyService service = new MyService();
MyServicePortType port = service.getMyServicePort();
// 2. 获取 HTTPClientPolicy
HTTPClientPolicy httpClientPolicy = ClientProxy.getClient(port).getHTTPClientPolicy();
// 3. 设置超时
httpClientPolicy.setConnectionTimeout(5000); // 5秒连接超时
httpClientPolicy.setReceiveTimeout(10000); // 10秒读取超时
// CXF 还支持更细粒度的超时控制
// httpClientPolicy.setConnectionRequestTimeout(3000); // 从连接池获取连接的超时
// 4. (可选) 设置重试策略
// httpClientPolicy.setAllowChunking(false); // 禁用分块传输,有时有助于解决超时问题
// 5. 调用 WebService
try {
String result = port.someMethod("some data");
System.out.println("调用成功: " + result);
} catch (Exception e) {
System.err.println("调用失败: " + e.getMessage());
e.printStackTrace();
}
}
}
服务端超时设置 (Server-side Timeout)
服务端超时指的是,当服务器接收到一个请求后,如果在指定的时间内无法处理完毕,就主动中断请求,并向客户端返回一个超时错误,这可以防止服务器线程长时间被一个慢请求占用,从而影响其他请求的处理。
JAX-WS 服务端超时设置 (在 Tomcat/JBoss 等 Servlet 容器中)
在标准的 JAX-WS 实现中,服务端超时通常不是直接通过 JAX-WS API 设置的,而是依赖于底层的 Servlet 容器(如 Tomcat)的配置。
在 Tomcat 中配置:
Tomcat 的 web.xml 文件中可以配置 Servlet 的超时。
<web-app ...>
<servlet>
<servlet-name>MyService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<!-- 设置 Servlet 超时为 30 秒 -->
<async-timeout>30000</async-timeout>
</servlet>
<servlet-mapping>
<servlet-name>MyService</servlet-name>
<url-pattern>/myservice</url-pattern>
</servlet-mapping>
</web-app>
<async-timeout>:
- 这个标签用于配置异步 Servlet 的超时时间(单位:毫秒)。
- 当一个请求被异步处理后,如果超过这个时间还没有完成,容器会调用
AsyncContext.complete()或AsyncContext.dispatch()来结束异步处理。 - 这对于处理长时间运行的任务非常有用。
对于同步请求,超时主要由 Servlet 容器的连接超时 控制,这通常在 server.xml 中配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" <!-- 连接建立后,等待请求的超时 -->
redirectPort="8443" />
Apache CXF 服务端超时设置
CXF 提供了更精细的控制,可以通过配置文件或编程方式来设置。
通过 cxf.xml 配置文件:
在 WEB-INF/cxf.xml 中配置 HTTP 传输器的超时。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http.xsd">
<!-- 配置 HTTP 传输器 -->
<http:destination name="{http://your.namespace/}MyServicePort.http-destination">
<http:server ConnectionTimeout="10000" ReceiveTimeout="30000"/>
</http:destination>
</beans>
ConnectionTimeout: 服务器端等待客户端连接建立的超时。- **`
