Как добавить XML-запрос к единственному дочернему элементу SOAP в теле SOAP? - PullRequest
0 голосов
/ 20 февраля 2019

Вариант использования

Мне нужно связаться с внешней службой SOAP программным способом.Для этого мне нужно создать SOAP-запрос, который выглядит следующим образом:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://myURI/">
   <soapenv:Header/>
   <soapenv:Body>
      <pric:myAPI>
        <XmlDocument>
            <OtherXmlContent>
            </OtherXmlContent>
        </XmlDocument>
      </pric:myAPI>
   </soapenv:Body>
</soapenv:Envelope>

Задача, на которой я заблокирован

Мне удается создать следующий конверт SOAP:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://myURI/">
   <soapenv:Header/>
   <soapenv:Body>
      <pric:myAPI>

      </pric:myAPI>
   </soapenv:Body>
</soapenv:Envelope>

Что мне нужно сделать, при условии ввода данных, это добавить запрос XML:

<XmlDocument>
    <OtherXmlContent>
    </OtherXmlContent>
</XmlDocument>

... как дочерний элемент <pric:myAPI>, который является единственным дочерним элементомmy <soapenv:Body>.

Для информации вышеупомянутый Мыльный конверт (пока не XmlDocument) создается с помощью следующего кода:

MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(pricingNamespace, pricingNamespaceURI);
SOAPBody soapBody = envelope.getBody();
SOAPElement pricingWrapper = soapBody.addChildElement(pricingAction, pricingNamespace);

... следовательно, что мне нужносделать, это добавить ребенка к pricingWrapper.Я выбираю способ создания этого дочернего элемента, у меня есть полный контроль над функцией, которая его генерирует:

private static String createXmlProductFromDealingDocument(Document dealings) 

Попытка 1 - добавление документа в виде текста

Я попытался добавитьXmlDocument как текст pricingWrapper.Вот как я это сделал:

pricingWrapper.addTextNode(createXmlProductFromDealingDocument(dealingFile));

Проблема, однако, состоит в том, что все символы < и > XmlDocument, отображаемые как String, экранируются методом addTextNode.Другими словами, я вижу, что мое тело имеет правильное содержимое, но < заменяется на &lt;, а > заменяется на &gt;, что делает запрос SOAP недействительным для целевой службы.

Попытка 2 - добавление документа в качестве дочернего узла

Другая попытка, которую я сделал, - вернуть Node вместо String из моей функции:

private static Node createXmlProductFromDealingDocument(Document dealings) 

и добавьте это Node как потомок pricingWrapper:

pricingWrapper.appendChild(createXmlProductFromDealingDocument(dealingFile));

Выше приведено исключение типа:

org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: Узел используется в документе, отличном от того, который его создал.

Хорошо, достаточно справедливо.Вчера я опубликовал вопрос (вскоре удаленный, поскольку я хотел углубиться в свои исследования), и пользователь любезно предложил мне в комментарии проверить, как клонировать узлы DOM, сославшись на этот ответ .

Я попытался сделать это следующим образом:

Node pricingRequest = createXmlProductFromDealingDocument(dealingFile);
Node soapPricingRequest = pricingRequest.cloneNode(true);
pricingWrapper.getOwnerDocument().adoptNode(soapPricingRequest);
pricingWrapper.appendChild(soapPricingRequest);

Однако возникает новое исключение:

org.w3c.dom.DOMException: NOT_SUPPORTED_ERR:Реализация не поддерживает запрошенный тип объекта или операции.

... в следующей строке:

pricingWrapper.getOwnerDocument().adoptNode(soapPricingRequest);

... и я действительно не понимаю, какиначе я мог бы добавить ребенка иначе, чем я делал выше.

Какой у меня вопрос

Я просто хотел бы правильно выполнить мой SOAP-запрос.У меня нет никаких предпочтений, будет ли это сделано путем введения XML в виде текста или в виде Node, насколько это правильно и особенно, насколько это работает :) Кто-нибудь, пожалуйста, напишите мне, как я могу исправить мойвышеуказанные вопросы?

1 Ответ

0 голосов
/ 20 февраля 2019

Чтение javadoc для acceptNode ():

DOMException - NOT_SUPPORTED_ERR: Повышается, если исходный узел имеет тип DOCUMENT, DOCUMENT_TYPE.".

Итак, не могли бы вы проверить, если soapPrincingRequest действительно тип узла DOCUMENT (используется getNodeType())?

Если это так, я бы посоветовал вампреобразовать soapPrincingRequest в Document, затем получить доступ к его корню NODE с помощью getDocumentElement() и попытаться adopt() этот NODE, а не DOCUMENT.

XML API, когда они стремятся к правильности, всегда немного обидчивы в использовании, и различие между Document и его root element на самом деле имеет значение. Так что это немного болезненно, но мы добираемся до конца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...