Я столкнулся с серьезной проблемой, заставившей клиента службы Java успешно взаимодействовать со службой WCF. Я преодолел множество препятствий, и считаю, что это мое последнее. Проблема сводится к тому, как Java Axis + WSS4J, кажется, обрабатывает пространства имен xml. Платформа Java кажется очень жесткой в том, что они ожидают от префиксов пространства имен xml, и поэтому не понимают сообщения ответа WCF.
Вкратце моя проблема заключается в следующем. У меня есть ответ в формате xml, подобный следующему из моей службы WCF:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1" u:Id="_3">http://tempuri.org/IProcessor/DoProcessingResponse</a:Action>
<h:CorrelationID xmlns:h="http://tempuri.org/">1234</h:CorrelationID>
<a:RelatesTo u:Id="_4">uuid:40f800a0-9613-4f4a-96c5-b9fd98085deb</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<!-- WS-Security header stuff -->
</o:Security>
</s:Header>
<s:Body u:Id="_1">
<e:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<e:CipherData>
<e:CipherValue>NfA6XunmyLlT2ucA+5QneoawHm+imcaCltDAJC1mRZOSxoB6YGpDLY1FyVykPbPGDoFGUESLsmvvbD62sNnRrgE+AuKPo+1CD3DF4LfurRcEv9A50ba9V+ViqlrhydhK</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body>
</s:Envelope>
В этом ответе для большинства вещей используются простые односимвольные префиксы пространства имен, такие как 's' для конверта SOAP, 'a' для WS-адресации, 'o' для 'WS-Security' и т. Д. Клиент Java, а именно WSS4J, кажется ожидать следующего:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action soap:mustUnderstand="1" wsu:Id="_3">http://tempuri.org/IProcessor/DoProcessingResponse</wsa:Action>
<h:CorrelationID xmlns:h="http://tempuri.org/">1234</h:CorrelationID>
<wsa:RelatesTo wsu:Id="_4">uuid:40f800a0-9613-4f4a-96c5-b9fd98085deb</a:RelatesTo>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<!-- WS-Security header stuff -->
</wsse:Security>
</soap:Header>
<soap:Body u:Id="_1">
<xenc:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>NfA6XunmyLlT2ucA+5QneoawHm+imcaCltDAJC1mRZOSxoB6YGpDLY1FyVykPbPGDoFGUESLsmvvbD62sNnRrgE+AuKPo+1CD3DF4LfurRcEv9A50ba9V+ViqlrhydhK</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>
После получения моего ответного сообщения клиент Java и WSS4J, похоже, хотят искать элементы по своим собственным внутренним псевдонимам xml, таким как «wsa» для WS-Addressing и «wsse» для расширений WS-Security. Поскольку ни одно из этих пространств имен не присутствует в фактическом ответе xml, возникают исключения.
Мне интересно, есть ли какой-либо простой способ преобразовать XML-документ из одного набора пространств имен в другой набор с использованием C #, .NET и пространства имен System.Xml. Я немного поработал с XmlNamespaceManager, но он, похоже, не полностью поддерживает то, что мне нужно ... или, по крайней мере, я не смог найти действительно полезных примеров и не совсем уверен, как это работает. Я пытаюсь избежать необходимости писать какой-то сложный процесс, чтобы справиться с этим вручную, поскольку я не хочу резко влиять на производительность наших служб при вызове клиентом Java Axis / WSS4J.