如何合并来自不同服务的WSDL和XSD中的公共部分?

22
我需要与一组 Web 服务交互,每个服务都有自己的 WSDL 和 XSD。XSD 有时在单个文件中合并,有时在多个文件中分散(20-30)。然而,通过经验我知道,大部分消息结构和数据共享一个大的公共子集,也许只有不同交易中的20%是不同的。
不幸的是,我无法控制服务器部分或服务的声明,因此让它们进行修复是行不通的。第一个客户端版本单独生成了每个服务,然后将它们用作个体外观来形成一个连贯的更高级别服务,作为另一个系统的适配器。
我使用默认的 JAXB 绑定和强制实施了不同的生成包以供每个服务使用 CXF。我这样做是因为一些服务使用共同数据模型,但不是所有服务都使用相同的版本或自定义,因此我存在冲突,因此选择了野蛮力量,以便我可以完成该系统。
然而,这会导致适配器的内存需求飙升,因为每个服务都会加载其上下文。现在,在发送请求和处理响应之前,我已经使用了超过500M的内存来容纳服务客户端的适配器。虽然我可以在当前情况下运行系统而没有问题,但这会创建约束,从而危及解决方案的部署;我的客户希望将这个系统的内存要求大幅降低(60%或更多),以便可以在不需要硬件升级的情况下安装该系统。
问题如下: 是否有工具或技术可以将每个事务的公共部分放在一起,使其可以生成一次并在需要时引用? 除了重新设计系统使用其他框架或数据绑定所需的时间外,我没有限制使用 CXF 或 JAXB。
提前感谢您的帮助。

谢谢 Blaise。这指向了 JAXB 的一个有用功能:episodes。不幸的是,我仍然需要提取不同服务的共同基础部分。所以现在我需要一种通过结构差异来提取这些公共部分的方法,即一种能够意识到 XSD 描述的结构和类型层次结构的差异工具,以便将适当的引用放置在公共部分与专业部分之间。


2
您可能会对EclipseLink JAXB(MOXy)中的以下相关功能感兴趣:https://bugs.eclipse.org/340997 - bdoughan
1
他们是否在使用共同的命名空间来共享部分?如果没有,那么你就很遗憾了,因为各个部分根本不知道它们是相同的。 - Donal Fellows
1Gb内存的价格是多少?你的时间价值多少钱?向客户指出这一点。 - artbristol
@donal:抱歉回复晚了,可能错过了评论通知。是的,幸运的是它们都共享相同的命名空间,理论上可以利用相似之处,至少在命名空间方面是可能的。 - Newtopian
@artbristol:确实,1G并不算太多,但是其他安全要求让我们在与交互式用户相同的Windows会话中运行整个程序。直到你需要在远程桌面服务器上部署时,会话从150m跳到1G+,对服务器负载的影响就不太实际了。尽管如此,我们已经将绑定于用户交互会话限制的部分与其余部分分开,现在“客户端”端更合理,只有15m。但是所有这些都无关紧要,因为老板说“不可接受!”并且不想听任何其他“借口”。 - Newtopian
2个回答

1

如果你想要减少一些负担,可以尝试使用其他的序列化技术(在任何框架中),比如放弃JAXB,尝试使用JiBX(已经添加到最新的CXF版本中)或者只是使用StAX。

由于你想要做一些比传统的JAX-WS/JAXB风格服务更加定制化的事情,你可能需要考虑Spring-WS。

Spring-WS让你控制Web服务栈的所有方面。它可以以不同的方式路由消息(payload、XPath表达式等),并且你可以使用任何你想要的序列化/反序列化技术(Jibx、jDOM、SAX等)。

这里有一个表格,说明了选项:

http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d4e1062

如果你真的想要变得高级一些,你可以使用其中一个较低级别的API,开始序列化消息,一旦你达到了某个常见区域的临界点,就可以立即启动JAXB序列化。

在Spring-WS中,将消息路由到不同的“端点”意味着您还可以执行诸如在此接口上“接受任何消息”之类的操作(看起来像DOM / SAX等),然后在那里进行一次大的编组操作。

Spring-WS的关键是让您摆脱JAX-WS模具,进行一些前期游戏,然后您始终可以稍后回到JAXB,无论是在拦截器、应用程序等中。理论上,您可以使用JAXB DOM Source完成相同的操作,但我认为Spring-WS堆栈为您提供了最精细的控制,以处理此类特殊情况。


我已尝试使用JiBX、XMLBeans和SDO作为JAXB的替代绑定,一些提供了一些好处,但它们的开销仍然太高,不太实用。在我的测试中,我能够获得的最佳内存增益约为20%,还不错,但我真正的目标是80%+... - Newtopian
Spring-WS提供了更多的功能,因此我最终选择了Spring-WS作为框架,原因与您所述基本相同。到目前为止,我们评估过的唯一可行解决方案是完全放弃XSD,并通过XML转换生成XML。这是迄今为止最好的答案! - Newtopian

-1
最好的技巧是提供一个静态的wsdl。只需打开wsdl,保存它,上传到服务器并告诉客户端指向静态的wsdl而不是动态自动生成的wsdl。

嗯...我遇到麻烦的是从WSDL生成代码,而不是反过来。实际上,我拥有的WSDL是由管理服务器端的人员提供的静态文件。哈,正如我所说,我无法访问服务器。也许我的问题表述不够清楚,但我相当确定已经涵盖了所有这些内容。 - Newtopian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接