春季-具有通用有效负载XML类型“ Any”的Web服务
作者:互联网
我已经开发了一种Web服务,该服务可以接受并以通用的消息结构进行响应.这意味着此消息结构是通用的.我们使之通用的方式是使用以下XML模式:
<xs:complexType name="HeaderType">
<xs:complexType name="MessageType">
<xs:complexType name="PayloadType">
其中PayloadType如下:
<xs:complexType name="PayloadType">
<xs:annotation>
<xs:documentation>Payload container</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:choice>
<xs:element name="CreateExceptionSeverity" type="cmsmsg:ExceptionSeverity" minOccurs="0">
<xs:annotation>
<xs:documentation>CreateExceptionSeverity is a hello world operation that takes in a app id, id, name, and description where the web service creates a new entry in EXCEPTIONSEVERITY table.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="OperationSet" type="cmsmsg:OperationSet" minOccurs="0">
<xs:annotation>
<xs:documentation>Each operation set is a collection of operations that may require operational-integrity and/or sequence control.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Compressed" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>For compressed and/or binary, uuencoded payloads</xs:documentation>
</xs:annotation>
</xs:element>
**<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" namespace="##other">**
<xs:annotation>
<xs:documentation>For XML payloads, usually CIM profiles defined using an XSD in a profile-specific namespace.</xs:documentation>
</xs:annotation>
</xs:any>
</xs:choice>
<xs:element name="Format" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>Hint as to format of payload, e.g. XML, RDF, SVF, BINARY, PDF, ...</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
因此,这一行:
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" namespace="##other">
使此结构足够灵活,以在调用Web服务和Web服务发回响应时发送数据.该Web服务部署在TIBCO服务器上(使用Tomcat),并将通过SOAP / HTTP调用.
该Web服务的客户端是Java Spring Web应用程序.我的问题是:Java代码如何处理此Any元素,因为它需要具体的XML类型,例如整数,字符串或复杂类型?在这里的任何方向将不胜感激.
解决方法:
请不要这样做.我以前使用过这类“通用” Web服务,它们相当于拥有一个Java API,其中每个方法都具有签名
public Object methodName(Object o);
是的,它们都是非常通用的,但是它没有传达有关如何使用它的信息(精心设计的界面传达了应如何使用它,就像茶壶的手柄建议将茶壶提起手柄一样) ).当某人想要开发使用您的服务的应用程序时,他们如何确定发送什么以及可以得到什么?如果在其他文档中,则说明您已经基本上创建了自己的定制Web服务描述语言,该语言不会与任何工具(如Spring或Axis-2)集成,并且需要编写很多额外的手动代码.
此外,您将不得不在服务实现中编写额外的代码来验证有效负载的内容.这意味着要进行额外的维护工作,并且出现缺陷的可能性更高.
请为您的Web服务操作使用具体的XML输入和响应,并摆脱任何输入和响应.它不仅使您的代码更简单,而且使消费者的代码更简单,而且还消除了您提出的关于如何从Spring中使用它的问题.
您不得不来这里询问如何使用已创建的Web服务这一事实应该引起您的警钟.创建任何类型的界面时,如果您难以使用它,那么其他人将很难使用.为了确保我的Web服务易于使用,我要做的第一件事(在创建WSDL或实现之前)是创建一个简单的程序,将该程序作为测试的一部分来调用该服务(例如,JUnit或Cucumber-JVM等) ,仅传入所需的数据(仅此而已),仅检查所需的响应数据(仅此而已).然后,我进行Web服务实现,直到测试通过.这总是会产生易于使用的好服务,而不是使用具有高度复杂模式的大型heavy肿服务,其中只有1%被使用(我确信他们将其余99%的模式放在了那里并且不使用它,只是使服务的新用户误入歧途).
对于要包含在消息中的元数据(即messageType和headerType信息),请考虑按照Messaging Metadata SOA Pattern使用SOAP Headers.它们使您可以包含其他信息,而不会污染消息正文.
最后,如果您需要对消息结构应用某种类型的一致性(由于某种奇怪的原因,SOAP信封不够用,并且您需要将自己的定制信封放入SOAP信封中),请考虑使用abstract base types,然后extend满足该方法的特殊需求.这将允许您应用一致性,而无需您的服务使用者猜测“ any”的实际含义.
边注.我工作过的一个客户有一个通用的消息结构,例如您的.原因之一是他们想要一种一致的方法来报告Web服务响应中的成功或错误.因此,在他们定制的响应信封中,有一个表示成功或失败的元素,而且一切都很好.
…除了服务的使用者外,他们现在需要编写额外的代码,不仅需要检查SOAP错误,还需要检查是否设置了定制错误标志.
…以及当我们想将负载平衡器放置在我们服务的前面时,因为它本身不支持我们定制的错误元素.但是,它确实支持SOAP错误和http状态代码:/
更新
一种简单的表达方式.该操作违反了Liskov substitution principle.
如果某个操作接受“任何”,我应该期望传递给该操作的任何有效xml元素都可以使用.但是,仅允许某些XML元素.知道允许哪些类型的唯一方法是知道操作的细节.换句话说,该操作不如所宣传的灵活.
以上更新是从https://softwareengineering.stackexchange.com/a/198100/37491的出色答案中修改而来的
标签:tibco,wsdl,web-services,spring,java-ee 来源: https://codeday.me/bug/20191122/2062603.html