将服务从Axis迁移到Axis2(Java) - 我应该使用哪个MessageReceiver?

时间:2010-04-07 19:13:03

标签: java xml soap web-services axis2

我正在将服务从Axis迁移到Axis2(Java)。该服务响应一个简单的SOAP请求,在主体中有一些“自定义”XML,如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header>
  <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
   <UsernameToken Id="MyID">
    <Username>user</Username>
    <Password>pass</Password>
   </UsernameToken>
  </wsse:Security>
  <dstm:ClientType xmlns:dstm="http://schemas.company.com/My_functions">Messaging.EWS</dstm:ClientType>
  <dstm:SessionScenario xmlns:dstm="http://schemas.company.com/My_functions">terminate</dstm:SessionScenario>
  <dstm:Organization xmlns:dstm="http://schemas.company.com/My_functions">*</dstm:Organization>
 </soapenv:Header>
 <soapenv:Body>
  <tt:processBodyMessage xmlns:tt="http://core.ws.com"/>
  <GetZipCode_001 version="1.0" xmlns="http://schema.company.com/Company/1">
   <Get>
    <ActionExpression>getEntity</ActionExpression>
   </Get>
   <ZipCodeID>
    <Id>10003</Id>
   </ZipCodeID>
  </GetZipCode_001>
 </soapenv:Body>
</soapenv:Envelope>

在Axis1中,该服务将一组org.wc3.dom元素作为参数进行处理,例如。

public Element[] processMessage(Element [] elems) { ... }

如果我将服务迁移到Axis2,我可以调用它,但调试显示elems数组为空。这是在一个主要是vanilla services.xml中使用RPCMessageReceivers:

<service name="Connector">
 <Description>
  Connector Service ported to Axis2
 </Description>
 <messageReceivers>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
  <messageReceiver  mep="http://www.w3.org/2004/08/wsdl/in-out"  class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
 </messageReceivers>
 <parameter name="ServiceClass" locked="false">com.ws.core.Service</parameter>
</service>

从我读到的关于Axis2的内容来看,在服务签名中使用DOM对象通常不是一个好主意,所以我尝试使用AXIOM OMElements:

public OMElement processMessage(OMElement e) { ... }

与RawXMLINOutMessageReceiver:

结合使用
<service name="Connector">
 <Description>
  Connector Service ported to Axis2
 </Description>
 <operation name="processMessage">
      <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
 </operation>
 <parameter name="ServiceClass" locked="false">com.ws.core.Service</parameter>
</service>

这样可以更好一点,但唯一传递给“e”的是SOAP主体的第一个元素。

如果我尝试更改方法签名以接受OMElements数组:

public OMElement processMessage(OMElement[] e) { ... }

我得到一个Axis2错误,抱怨没有方法可以实现所需的方法签名。

我也尝试过使用带有RPCMessageReceiver的OMElements数组,但是这会导致传入一个空数组。

有人可以提供关于我可以使用哪种接收器/方法签名组合来访问SOAP请求正文中所有XML元素的建议吗?提前致谢。

1 个答案:

答案 0 :(得分:1)

这里的真正问题是Axis1服务正在处理有效的DOM,但是SOAP请求格式错误。根据{{​​3}},“根元素是一个杰出元素,它是soap:Body或soap:Header元素的直接后代。 soap:Body只有一个根元素,表示调用,响应或故障对象。“您可以看到SOAP主体有多个根元素,这些元素不符合标准:

<soapenv:Body>
  <tt:processBodyMessage xmlns:tt="http://core.ws.com"/>
  <GetZipCode_001 version="1.0" xmlns="http://schema.company.com/Company/1">
   ...
  </GetZipCode_001>
 </soapenv:Body>

最后,我选择使用RAWXMLINOutMessageReceiver及其标准服务条目签名:

public OMElement processMessage(OMElement e) { ... }

如果您需要访问此方法中的其他SOAP信封,您可以通过MessageContext访问它们,例如

SOAPEnvelope envelope = MessageContext.getCurrentMessageContext().getEnvelope();
SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();