Миграция службы с Axis на Axis2 (Java) — какой MessageReceiver следует использовать?

Я занимаюсь переносом службы с 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 пуст. Это использует RPCMessageReceivers в основном в vanilla services.xml:

<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, жалующееся на отсутствие метода, реализующего требуемую сигнатуру метода.

Я также пытался использовать массив OMElements с RPCMessageReceiver, но это приводит к передаче пустого массива.

Может ли кто-нибудь дать совет о том, какую комбинацию подписи получателя/метода я могу использовать для получения доступа ко всем элементам XML в теле запроса SOAP? Заранее спасибо.


person Justin Garrick    schedule 07.04.2010    source источник


Ответы (1)


Настоящая проблема здесь заключалась в том, что служба Axis1 обрабатывала действительный DOM, но неправильно формировала запросы SOAP. Согласно http://msdn.microsoft.com/en-us/magazine/bb985060.aspx, "Корневой элемент — это выделенный элемент, который является непосредственным потомком элемента 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();
person Justin Garrick    schedule 09.04.2010