SOAP-сообщение с javax.xml.soap - ошибка пространства имен? - PullRequest
4 голосов
/ 22 августа 2011

Ниже приведен общий пример запроса SOAP для веб-службы .NET, который я должен вызывать из моего веб-приложения java:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
  <setAMRequestData xmlns="http://tempuri.org/">
    <id>int</id>
  </setAMRequestData>
 </soap:Body>
</soap:Envelope>

Я могу сгенерировать что-то похожее из консольного приложения Java, используя этот сегмент кода:

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
...
SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage sm = mf.createMessage();

SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", XMLConstants.DEFAULT_NS_PREFIX);
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName n = new QName("id");                                          
SOAPElement quotation = bodyElement.addChildElement(n);
quotation.addTextNode("121152");

Результатом является следующий XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
  <setAMRequestData xmlns="http://tempuri.org/">
   <id>121152</id>
  </setAMRequestData>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Это вызывает сервис. Затем я использовал soapUI , чтобы попытаться вызвать этот сервис, и он сгенерировал мыльное сообщение из WSDL следующим образом (оно отличается от от предыдущего в объявлении пространства имен в конверте и префиксах):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tem="http://tempuri.org/">
 <soapenv:Header/>
  <soapenv:Body>
   <tem:setAMRequestData>
     <tem:id>?</tem:id>
   </tem:setAMRequestData>
  </soapenv:Body>
 </soapenv:Envelope>

Это также работает с soapUI. Но, наконец, когда я попытался воссоздать эту форму мыльного сообщения, используя следующую последовательность кода:

// factories and stuff, like in the example above
SOAPPart part = sm.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("tem", "http://tempuri.org/");

SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();

QName bodyName = new QName(null, "setAMRequestData", "tem");
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName n = new QName(null, "id", "tem");
SOAPElement quotation = bodyElement.addChildElement(n);
quotation.addTextNode("7028");

Я получил следующее исключение в строке Цитата SOAPElement = bodyElement.addChildElement (n); :

org.w3c.dom.DOMException: NAMESPACE_ERR: Предпринята попытка создать или изменить объект способом, который является неправильным в отношении пространств имен.

Независимо от того, что я пытался, я просто не мог установить префикс "tem" для элемента id ... Что здесь происходит?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 22 августа 2011

Вы связываете uri пространства имен с префиксом, а затем пытаетесь создать элемент с таким же префиксом, но с пустым uri пространства имен:

envelope.addNamespaceDeclaration("tem", "http://tempuri.org/");
...
QName bodyName = new QName(null, "setAMRequestData", "tem");

Элемент идентифицируется комбинацией пространства имен uri и локального имени. Чтобы решить эту проблему, вы должны указать пространство имен для каждого создаваемого вами элемента:

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", "tem");
...
QName n = new QName("http://tempuri.org/", "id", "tem");
1 голос
/ 22 августа 2011

Не работайте, потому что XML, выходящий из вашего приложения, не выглядит точно так же (особенно с префиксами пространства имен), как запрос, сделанный SoapUI. Вставьте свой код в запрос SoapUI, щелкните правой кнопкой мыши, переформатируйте и посмотрите, понимает ли SoapUI ваши вещи (и, если у вас есть профессиональная версия, проверьте ее в форме и в виде схемы). Если все выглядит нормально, запустите его и посмотрите, получите ли вы тот же ответ, что и на собственный запрос (soapUI). Если это так, вы хорошо идти. Однако, если что-то не так, пространства имен искажены, SoapUI не может отобразить ваш XML, значит, в вашем коде есть кое-какие настройки.

...