CXF 客户端为服务和端口加载 wsdl?

发布于 2025-01-04 16:47:24 字数 968 浏览 1 评论 0原文

在 java web 应用程序中,我需要调用远程肥皂服务,并且我正在尝试使用 CXF 2.5.0 生成的客户端。 Soap 服务由特定的 ERP 供应商提供,其 wsdl 非常庞大,有数千种类型、数十个 xsd 导入等。由于 -autoNameResolution 标志,wsdl2java 可以正常生成客户端。但在运行时,它会检索远程 wsdl 两次,一次是在我创建服务对象时,另一次是在我创建端口对象时。

MyService_Service myService = new MyService_Service(giantWsdlUrl);  // fetches giantWsdl
MyService myPort = myService.getMyServicePort();  // fetches giantWsdl again

这是为什么?我可以理解在创建 myService 时检索它,您希望看到它与我当前使用的客户端匹配,或者让运行时 wsdl 位置指示端点地址等。但我不明白为什么请求端口会重新加载它刚刚发布的所有内容。我错过了什么吗?

由于这是在 Web 应用程序中,并且我无法确定 myPort 是threadsafe,那么我就必须为每个线程创建一个端口,不过这太慢了,由于可怕的 wsdl,需要 6 到 8 秒。或者添加我自己的池,提前创建一堆,然后进行签出和签入。恶心。

根据记录,JaxWsProxyFactoryBean 创建路由不会获取 wsdl,这对于我的情况。第一次 create() 仍然需要很长时间,然后后续 create() 需要大约四分之一秒,甚至这也不太理想。我不知道……感觉就像我在幕后热线连接东西而不是转动钥匙。 :)

In a java web app, I need to call a remote soap service, and I'm trying to use a CXF 2.5.0-generated client. The soap service is provided by a particular ERP vendor, and its wsdl is monstrous, thousands of types, dozens of xsd imports, etc. wsdl2java generates the client ok, thanks to the -autoNameResolution flag. But at runtime it retrieves the remote wsdl twice, once when I create the service object, and again when I create a port object.

MyService_Service myService = new MyService_Service(giantWsdlUrl);  // fetches giantWsdl
MyService myPort = myService.getMyServicePort();  // fetches giantWsdl again

Why is that? I can understand retrieving it when creating myService, you want to see that it matches the client I'm currently using, or let a runtime wsdl location dictate the endpoint address, etc. But I don't understand why asking for the port would reload everything it just went out on the wire for. Am I missing something?

Since this is in a web application, and I can't be sure that myPort is threadsafe, then I'd have to create a port for each thread, except that's way too slow, 6 to 8 seconds thanks to the monstrous wsdl. Or add my own pooling, create a bunch in advance, and do check-outs and check-ins. Yuck.

For the record, the JaxWsProxyFactoryBean creation route does not ever fetch the wsdl, and that's good for my situation. It still takes a long time on the first create(), then about a quarter second on subsequent create()s, and even that's less than desirable. And I dunno... it sorta feels like I'm under the hood hotwiring the thing rather than turning the key. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寒冷纷飞旳雪 2025-01-11 16:47:24

嗯,其实你自己已经回答了这个问题。每次调用 service.getPort() 时,都会从远程站点加载 WSDL 并进行解析。 <一href="http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.web/3.1.0/org/springframework/remoting/jaxws/JaxWsPortClie ntInterceptor.java#JaxWsPortClientInterceptor.FeaturePortProvider.getPortStub%28javax.xml.ws.Service%2Cjavax.xml.namespace.QName%2Cjava.lang.Object%5b%5d%29" rel="nofollow">JaxWsProxyFactoryBean 的方式完全相同,但是一旦获得代理,它就会被重新用于进一步的调用。这就是为什么第一次运行很慢(因为“热身”),但后续运行很快。

是的,JaxWsProxyFactoryBean 不是线程安全的。池化客户端代理是一种选择,但不幸的是会消耗大量内存,因为 JAX-WS 运行时模型是不在客户端代理之间共享;同步也许是更好的遵循方式。

Well, you have actually answered the question yourself. Each time you invoke service.getPort() the WSDL is loaded from remote site and parsed. JaxWsProxyFactoryBean goes absolutely the same way, but once the proxy is obtained it is re-used for further invocations. That is why the 1st run is slow (because of "warming up"), but subsequent are fast.

And yes, JaxWsProxyFactoryBean is not thread-safe. Pooling client proxies is an option, but unfortunately will eat a lot of memory, as JAX-WS runtime model is not shared among client proxies; synchronization is perhaps better way to follow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文