Перенос службы из Axis в Axis2 (Java) - какой MessageReceiver мне следует использовать? - PullRequest
1 голос
/ 07 апреля 2010

Я в процессе миграции службы из 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>

Это работает немного лучше, но единственное, что передается в "е", это первый элемент тела SOAP.

Если я пытаюсь изменить сигнатуру метода, чтобы принять массив OMElements:

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

Я получаю сообщение об ошибке Axis2 с жалобой на то, что не существует метода, реализующего требуемую сигнатуру метода.

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

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

1 Ответ

1 голос
/ 09 апреля 2010

Реальная проблема здесь заключалась в том, что служба 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();
...