【问题标题】:Setting jax-ws client timeout设置 jax-ws 客户端超时
【发布时间】:2011-03-09 00:54:24
【问题描述】:

我无法设置 jax-ws 超时。我的代码是:

@WebServiceClient(name = "VoipDBJDBCService", targetNamespace = "http://db.server.voipmeter.jextreme.eu/", wsdlLocation = "http://trace0.nyc.blinkmind.com:8080/voipdb?wsdl")
public class VoipDBJDBCService extends Service {
    public VoipDBJDBCService(URL wsdlLocation) {
        super(wsdlLocation, new QName("http://db.server.voipmeter.jextreme.eu/", "VoipDBJDBCService"));
    }

    @WebEndpoint(name = "VoipDBJDBCPort")
    public VoipDB getVoipDBJDBCPort() {
        return super.getPort(new QName("http://db.server.voipmeter.jextreme.eu/", "VoipDBJDBCPort"), VoipDB.class);
    }
}

及用法:

VoipDB db = new VoipDBJDBCService(new URL(url)).getVoipDBJDBCPort();

我如何挂钩超时?我在这里找到了“解决方案”:https://jax-ws.dev.java.net/guide/HTTP_Timeouts.html 但我不知道我应该把它挂在哪里。如何获得代理?当我调用 getPort 时,客户端尝试连接,然后如果服务器没有响应则永远挂起。

更新: 如果有任何区别,则从 applet init() 方法中调用此代码。

【问题讨论】:

    标签: java web-services jax-ws


    【解决方案1】:

    与 Metro/Glassfish...

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

    【讨论】:

    • 实际上这就是第一个答案中所说的(以及问题本身)如果有人不害怕与 Sun 合作,import com.sun.xml.ws.developer.JAXWSProperties 并使用 JAXWSProperties.CONNECT_TIMEOUTJAXWSProperties.REQUEST_TIMEOUT 也可能是有意义的内部结构。
    • 如何获取 wsPort 实例?
    • Eww,字符串键。正是我不应该在类型安全的语言中看到的。设计这个 API 的人应该在火中燃烧。
    【解决方案2】:
    ProxyWs proxy = (ProxyWs) factory.create();
    Client client = ClientProxy.getClient(proxy);
    HTTPConduit http = (HTTPConduit) client.getConduit();
    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
    httpClientPolicy.setConnectionTimeout(0);
    httpClientPolicy.setReceiveTimeout(0);
    http.setClient(httpClientPolicy);
    

    这对我有用。

    【讨论】:

      【解决方案3】:

      如果您使用的是 Sun JRE,您可以为默认网络连接和读取超时(以毫秒为单位)设置以下系统属性。我没有在 JAX-WS 客户端上尝试过这些,但它们也应该在那里工作:

      sun.net.client.defaultConnectTimeout
      sun.net.client.defaultReadTimeout
      

      补充:我错过了问题的最后一部分,您说您在小程序中执行此操作。如果小程序以默认权限运行,则可能不允许您设置系统属性。

      【讨论】:

      • 小程序已签名。这很难重现。因为客户端在服务器挂起时挂起(而不是在停机时)。
      • 你可以用这个服务器代码模拟一个挂起的TCP服务器:ServerSocket serverSocket = new ServerSocket(PORT); while (true) { serverSocket.accept();只需接受,但不要在“虚拟服务器”端读取或写入任何内容。
      【解决方案4】:

      您可以将VoipDB 对象转换为BindingProvider。因此,在您给出的链接中的示例中,只需将 proxy 替换为 db 即可。

      【讨论】:

      • 这实际上不起作用,因为客户端挂在调用 getPort 的行上。
      • 嗯,这就是你可以用链接中提供的方法做的所有事情。 jax-ws 下载服务的 WSDL 以创建代理。这很可能是给您带来麻烦的原因。我现在唯一能想到的就是下载 WSDL 的本地副本并使用它,但这当然不是很优雅......
      【解决方案5】:

      这是一个例子

      public void testConfigureTimeout() throws Exception
      {
         //Set timeout until a connection is established
         ((BindingProvider)port).getRequestContext()
         .put("javax.xml.ws.client.connectionTimeout", "6000");
      
         //Set timeout until the response is received
         ((BindingProvider) port).getRequestContext()
         .put("javax.xml.ws.client.receiveTimeout", "1000");
      
          port.echo("testTimeout");
      }
      

      【讨论】: