我正在使用一些遗留组件,我们使用JAXRPC-RI(参考实现)库构建的一些客户端代码与SOAP Web服务(我绝对,非常厌恶的技术)进行交互。 / p>
我对能够使用存根设置超时感兴趣,以便万一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客户端时如何设置/强制执行超时有任何想法?它甚至可能吗?
答案 0 :(得分:4)
您可能有运气设置属性,例如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" ...
答案 1 :(得分:2)
我不确定为什么这个特定的JAXRPC实现会让它很难设置超时。也许,这是有充分理由的。其他实现,比如Axis,我相信JAX-WS,让你只需在Stub上调用setTimeout()方法。经过一些痛苦,我能够想出这个解决方案。希望它会有所帮助。您需要执行以下操作才能在基础URLConnection上设置超时:
注意:确保您通过wscompile(Ant脚本?)生成Stubs的任何内容都不会覆盖您刚刚创建/修改的3个Java类。将它们移动到不同的包可能是有意义的,这样它们就不会被覆盖。
答案 2 :(得分:1)
Yevgeniy Treyvus的回答非常好,但是会为每个SOAP调用创建一个新的HTTPUrlConnection。 我在测试他的方法时发现,可以设置ClientTransportFactory。 我现在使用CustomClientTransportFactory并将其设置在Stub上(将其转换为StubBase)。 然后一个人不需要第2步和第3步。
在第4步中,然后设置新的ClientTransportFactory,如下所示: ((StubBase)myPort)._ setTransportFactory(new CustomClientTransportFactory());
答案 3 :(得分:0)
我只是想尝试获得赏金,所以如果我完全走错了路,请不要开枪。:)如果你的应用程序“在那里永远等待响应”,那么你可以做到这一点在一个单独的线程中,在产生requestThread
之后你可以说requestThread.join(max_time_to_wait);
,下一次调用将检查requestThread是否仍然存活,如果是,则尝试杀死它。
您的应用程序将在超时后继续运行,并且它不是最不优雅的解决方案......
答案 4 :(得分:0)
雷
感谢您的投入。听起来你的方法很优越,因为它可以避免一些无关紧要的步骤。我得去看看。但是,除非我遗漏了一些内容,否则我不相信会创建额外的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;
}
}
答案 5 :(得分:0)
我知道您正在使用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但它错误地指出超时是以秒为单位。它实际上是以毫秒为单位!
答案 6 :(得分:0)
这个问题可能有点迟了但我今天遇到了这个问题。 根据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提出的基本相同,但有一点不太重要(在连接工厂的帮助下)。
答案 7 :(得分:-1)
您应该使用:
import javax.xml.rpc.Stub;
...
int timeout = <number of milliseconds>;
((Stub) port)._setProperty(
"axis.connection.timeout",
timeout);