作为广泛合作的一部分,我们正在与第三方提供的网络服务进行交互,该服务向我们提供了其.wsdl / .xsd服务描述。
.wsdl文件描述了表示故障的三种类型的消息。 它们都包装相同的元素类型。 .wsdl文件中的相对部分如下所示:
<message name="ExceptionType1">
<part name="fault" element="customNamespace:customCommonType"/>
</message>
<message name="ExceptionType2">
<part name="fault" element="customNamespace:customCommonType"/>
</message>
<message name="ExceptionType2">
<part name="fault" element="customNamespace:customCommonType"/>
</message>
<portType name="portTypeName">
<operation name="opName">
<input [...] />
<output [...] />
<fault message="customNamespace:ExceptionType1" name="ExceptionType1"/>
<fault message="customNamespace:ExceptionType2" name="ExceptionType2"/>
<fault message="customNamespace:ExceptionType3" name="ExceptionType3"/>
</operation>
</portType>
我们正在使用 Axis2 1.7.9 生成数据类型和服务存根。我们还生成了一个内部测试服务框架。
对于三种类型的故障,Axis2生成三个类,每个扩展Exception
和的类型为CustomCommonType
(同样由Axis2根据XSD描述生成)。
在识别我的Axis2生成的存根接收到的故障类型方面,我们遇到了两个方面的问题:
populateFaults
用每种故障类型的一个条目填充两个HashMap<org.apache.axis2.client.FaultMapKey, String>
对象faultExceptionNameMap
和faultExceptionClassNameMap
。问题是FaultMapKey
每次都用QName
进行参数化,customCommonType
是opName
和<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>
This is the string that gets passed to the
constructor Exception(String),
inherited by the three custom exceptions
</faultstring>
<detail>
<customNamespace:customCommonType xmlns:customNamespace="<url>">
[contents of CustomCommonType]
</customNamespace:customCommonType>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
的全限定名; 这将导致每个映射覆盖先前的映射,每个映射最后按插入顺序仅具有最后一个异常类名称。当我从Axis2生成的Skeleton中抛出三个异常时,我收到的响应总是像这样(使用SoapUI获得的响应):
ExceptionType1 t1 = new ExceptionType1("[What is in <faultstring>]");
CustomCommonType cct;
[...]
//Configure a proper cct object
[...]
t1.setCustomCommonType(cct);
throw t1;
引发异常的代码是:
CustomCommonType
Skeleton方法本身接受有效负载对象,并返回由Axis2生成的响应对象 。除了强制执行xsd定义的约束并包括一些用于[反序列化]的功能外,这些对象以及soapenv.Server.X
还可以有效地充当DTO ,这意味着提供了设置状态代码或其他响应属性的功能,骨架本身也没有(生成的骨架仅包含与服务接口相对应的空方法)。
无论抛出三种故障中的哪一种,响应消息都应该相同。
目前,我们在此项目中没有合作伙伴进行测试的WS端点,因此我们无法确定其响应应采用哪种格式(例如,自定义{{1 }}错误代码),并因此实现一些临时逻辑来覆盖存根的默认值。
我想知道的是:这更多是Axis2框架的问题(不是整理异常的特定于异常的信息,即类名),表示这是我们这边的问题是,我们必须自己解决这个问题(更改框架/自己重新发明轮子/要求我们的合作伙伴将某些信息集成到commonCustomType xsd定义中),或者是服务定义有些不寻常?
我自己研究了spring-ws模块进行备份,并且看到它基于发布的.wsdl 中基于元素定义中的后缀生成请求,响应和故障元素。 .xsd文件(并将它们封装在适当命名的操作和端口类型中)(documentation)。即使在技术上仅是 一个实现,并且WSDL 1.2 specification表示“一个操作可能具有零个或多个故障消息属性” ,但 spring- ws 后缀方法似乎强化了这样的观念,即一个操作最多应该具有一个错误。在我刚刚描述的情况下,这种(隐式)假设似乎是Axis2行为的基础。