Java 当WSDL太大时,JAX-WS客户端将挂起30秒

Java 当WSDL太大时,JAX-WS客户端将挂起30秒,java,wsdl,jax-ws,blocking,Java,Wsdl,Jax Ws,Blocking,我对JAX-WSWebServices和ApacheCXF有点陌生。我们正在开发一个简单的客户机-服务器系统,它们之间的通信是通过JAX-WSWeb服务协议进行的。在服务器端,我们使用apachecxf实现(因为使用了拦截器),在客户端,它是正常的引用实现(jax-ws-rt) 我的问题如下:当客户端首先创建服务时: service = Service.create(uri.toURL(), new QName(targetNamespace, serviceName)); 然后它通常向服务器

我对JAX-WSWebServices和ApacheCXF有点陌生。我们正在开发一个简单的客户机-服务器系统,它们之间的通信是通过JAX-WSWeb服务协议进行的。在服务器端,我们使用apachecxf实现(因为使用了拦截器),在客户端,它是正常的引用实现(jax-ws-rt)

我的问题如下:当客户端首先创建服务时:

service = Service.create(uri.toURL(), new QName(targetNamespace, serviceName));
然后它通常向服务器发送GET请求,以便获取和处理WSDL。首先是这样的:

GET .../services/ws/mainservice?wsdl
然后紧接着

GET .../services/ws/mainservice?wsdl=mainservice.wsdl
到目前为止,一切顺利。第三个请求是正常的HTTPPOST请求,使用SOAP调用客户端调用的函数

在WSDL变得太大之前,一切都正常工作。我可以通过网络浏览器查看尺寸,例如,使用上面的两个GET链接。当第二个GET请求的响应达到100K大小(浏览器中的XML响应)时,由于web服务接口中声明的函数太多,会发生以下情况:客户端在第二个GET请求期间挂起约30秒,然后一切正常,函数运行

我调试了,在这种情况下,哪一点被阻塞了,当它调用以下内容时,它位于RuntimeWSDLParser.java,createReader()函数中:

private static XMLStreamReader createReader(URL wsdlLoc, Class<Service> serviceClass) throws IOException, XMLStreamException {
InputStream stream;
try {
    stream = wsdlLoc.openStream();
} catch (IOException io) {

}
私有静态XMLStreamReader createReader(URL wsdlLoc,类serviceClass)抛出IOException、XMLStreamException{
输入流;
试一试{
stream=wsdlLoc.openStream();
}捕获(io异常){
}
这个文件位于客户端的jax-ws-rt.jar中

奇怪的是(至少对我来说,但我不是很熟悉),如果我使用调试器到达这一行,并立即跳过,那么阻塞时间大约为30秒。如果我等待25秒,然后跳过,则仅为5秒。因此,似乎在某个地方挂着一个计数器

另一件事:这个问题只发生在我使用本地主机连接时。如果我尝试使用与另一台计算机不同的客户端,并使用内部IP地址,则不会发生阻塞。当我尝试使用TCPMon并重定向端口时也不会发生阻塞


我希望我说的够具体。如果您能提供任何帮助,我们将不胜感激,我已经为这个问题困扰了好几天。提前谢谢!

今天您很幸运!有两种选择:

  • 在本地使用WSDL文档文件 将WSDL文档文件和schemma文件的副本保存到项目中

    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    URL wsdlLocation = classloader.getResource("MyHelloService.wsdl");
    QName serviceName= new QName("http://test.com/", "MyHelloService");
    
    MyHelloService service = new MyHelloService(wsdlLocation, serviceName);
    service.sayHello("Test");
    
  • 没有WSDL文档文件

  • 另见:


    我在服务器端保存了一个副本,也替换了本地文件的导入,然后我调整了两个设置:1)我在实现WebService类的@WebService标记中添加了wsdlLocation属性,2)在客户端,我使用此链接作为uri。很好,谢谢!此外,我尽可能深入地调试了问题。在在服务器端,有一些已同步(端点)在jetty HttpConnection中阻塞,并且它在返回数据后无法关闭outputstream。因此,在第一个请求之后,服务器端端点被阻塞30秒,这是读取超时的默认设置。然后,可以处理第二个请求。关于它取决于wsdl大小,我相信这是jetty错误。您是否已确认e服务客户机类中的
    静态
    块?您可以修改它以避免加载远程WSDL和本地文件。
    QName qname = new QName("http://thenamespace", "FooService");
    FooService service = new FooService(null, qname); // null for ignore WSDL
    Foo port = service.getFooPort();
    BindingProvider bindingProvider = (BindingProvider) port;
    bindingProvider.getRequestContext()
        .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
        "http://foo.com/soap/fooBean");
    
    // Use the service
    Object obj = port.doSomething(param);