[英]How to set a connection timeout when using JAXRPC-RI web services client?
我正在使用一些遗留组件,我们使用JAXRPC-RI(参考实现)库构建的一些客户端代码与SOAP Web服务(我绝对,积极地厌恶的技术)进行交互。
我有兴趣能够使用存根设置超时,以便万一Web服务器在X秒内没有回复,应用程序不会在那里永远等待响应。
我正在使用Apache Axis生成的客户端/存根,您可以在其中使用org.apache.axis.client.Stub.setTimeout()
来设置超时。
对于我的生活,我无法弄清楚在使用JAXRPC-RI创建的存根时如何设置超时:
com.sun.xml.rpc.client.StubBase
并实现了javax.xml.rpc.Stub
和com.sun.xml.rpc.spi.runtime.StubBase
。 stub._setProperty("axis.connection.timeout", 1000);
在运行时导致异常: javax.xml.rpc.JAXRPCException: Stub does not recognize property: axis.connection.timeout
有没有人对使用JAXRPC-RI客户端时如何设置/强制执行超时有任何想法? 它甚至可能吗?
您可能有运气设置属性,例如sun.net.client.defaultConnectTimeout
或sun.net.client.defaultReadTimeout
,但这会引入系统范围的超时。
在代码中,使用字符串设置属性值:
System.setProperty("sun.net.client.defaultConnectTimeout", "1000");
System.setProperty("sun.net.client.defaultReadTimeout", "1000");
对于快速测试,可能更容易设置环境变量JAVA_OPTS
或使用命令行:
java -Dsun.net.client.defaultConnectTimeout="1000" ...
我不确定为什么这个特殊的JAXRPC实现会让它很难设置超时。 也许,这是有充分理由的。 其他实现,比如Axis,我相信JAX-WS,让你只需在Stub上调用setTimeout()方法。 经过一些痛苦,我能够想出这个解决方案。 希望它会有所帮助。 您需要执行以下操作才能在基础URLConnection上设置超时:
注意:确保您通过wscompile(Ant脚本?)生成Stubs的任何内容都不会覆盖您刚刚创建/修改的3个Java类。 将它们移动到不同的包可能是有意义的,这样它们就不会被覆盖。
我知道您正在使用Axis,但我很难为Weblogic找到相同的答案,因为您的问题标题和标签是通用的,这是我的解决方案。
在我实现生成的MyObject接口的客户端类中,我已经调整了getServicePort(),如下所示(注意我在这里也有安全性)。
protected MyObject getServicePort() throws java.rmi.RemoteException {
if (port == null) {
synchronized(this) {
if (port == null) {
try {
final MyObject_Impl service = new MyObject_Impl(wsdlURL);
// using a local variable until the object is completelly initialized
final MyObject localPort = service.getMyObjectPort();
// if username and password are provided: building a client which will include the
// username and token
if (username != null && pwd != null) {
Stub localStub = ((Stub) localPort);
// We have UsernameToken Authentication too
localStub._setProperty(
WSSecurityContext.CREDENTIAL_PROVIDER_LIST,
Collections.singletonList(
new ClientUNTCredentialProvider(username.getBytes(), pwd.getBytes())));
if (timeout != null) {
log.debug("Setting timeout to " + timeout + " milliseconds");
localStub._setProperty("weblogic.wsee.transport.read.timeout", timeout);
localStub._setProperty("weblogic.wsee.transport.connection.timeout", timeout);
}
}
port = localPort;
} catch (ServiceException e) {
throw new RemoteException("Could not initialize client to MyObject service", e);
}
}
}
}
return port;
}
Oracle文档位于: http : //docs.oracle.com/cd/E12840_01/wls/docs103/webserv_rpc/client.html#wp241849但它错误地指出超时是以秒为单位。 它实际上是以毫秒为单位!
Yevgeniy Treyvus的答案非常好,但是会为每个SOAP调用创建一个新的HTTPUrlConnection。 我在测试他的方法时发现,可以设置ClientTransportFactory。 我现在使用CustomClientTransportFactory并将其设置在Stub上(将其转换为StubBase)。 然后一个人不需要第2步和第3步。
在步骤4中,然后设置他的新ClientTransportFactory,如下所示:((StubBase)myPort)._ setTransportFactory(new CustomClientTransportFactory());
也许这个问题有点迟了但我今天遇到了这个问题。 根据Yevgeniy Treyvus提出的解决方案(谢谢它!),我想出了以下内容:
((com.sun.xml.rpc.client.StubBase)myRemoteStub)._setTransportFactory(new ClientTransportFactory() {
@Override
public ClientTransport create() {
return new HttpClientTransport() {
@Override
protected HttpURLConnection createHttpConnection(String endpoint, SOAPMessageContext context) throws IOException {
HttpURLConnection conn = super.createHttpConnection(endpoint, context);
conn.setConnectTimeout(2000);
conn.setReadTimeout(2000);
return conn;
}
};
}
});
它基本上与Yevgeniy提出的相同,但有一点不太重要(在连接工厂的帮助下)。
射线,
感谢您的输入。 听起来你的方法很优越,因为它可以避免一些无关紧要的步骤。 我得去看看。 但是,除非我遗漏了一些内容,否则我不相信会创建额外的HttpConnection,因为YourClientTransport.createHttpConnection(String s,SOAPMessageContext ctx)应该覆盖HttpClientTransport:
public class YourClientTransport extends HttpClientTransport {
@Override
protected HttpUrlConnection createHttpConnection(String s, SOAPMessageContext ctx) throws IOException {
HttpURLConnection httpURLConnection = super.createHttpConnection(s, ctx);
httpURLConnection.setReadTimeout(1000);
httpURLConnection.setConnectTimeout(1000);
return httpURLConnection;
}
}
我只是想收获赏金,所以如果我完全走错了轨道就不要开枪了:)如果你的应用程序“永远在那里设置等待响应”,那么你可以单独做出请求线程并在产生requestThread
你可以说requestThread.join(max_time_to_wait);
下一个调用将检查requestThread是否仍然存在,如果是,那么尝试杀死它。
您的应用程序将在超时后继续运行,并且它不是最不优雅的解决方案......
你应该使用:
import javax.xml.rpc.Stub;
...
int timeout = <number of milliseconds>;
((Stub) port)._setProperty(
"axis.connection.timeout",
timeout);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.