Java 当WSDL太大时,JAX-WS客户端将挂起30秒
我对JAX-WSWebServices和ApacheCXF有点陌生。我们正在开发一个简单的客户机-服务器系统,它们之间的通信是通过JAX-WSWeb服务协议进行的。在服务器端,我们使用apachecxf实现(因为使用了拦截器),在客户端,它是正常的引用实现(jax-ws-rt) 我的问题如下:当客户端首先创建服务时: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)); 然后它通常向服务器
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并重定向端口时也不会发生阻塞
我希望我说的够具体。如果您能提供任何帮助,我们将不胜感激,我已经为这个问题困扰了好几天。提前谢谢!今天您很幸运!有两种选择:
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和本地文件。
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);