Реакция SOAP ColdFusion с вложениями
Я использую Coldfusion9 для взаимодействия со сторонней SOAP-службой, с которой мне нужно отправлять и получать SOAP с вложениями. У меня нет проблем с получением SOAP, который может иметь или не иметь двоичные вложения, используя ToString() вокруг содержимого HTTP, чтобы преобразовать SOAP Body в полезную строку, однако для службы требуется, чтобы я отправлял свой ответ обратно с помощью вложений где я собираюсь отменить. Я никогда не делал этого в ColdFusion, и я не совсем уверен, как я должен представить это исходной службе, чтобы на SOAP-тело ссылались через идентификатор.
Ниже приведен синтаксический анализ входящих SOAP-данных с вложениями:
<cfset soapData = GetHttpRequestData()>
<!--- Loop over the HTTP headers and dump the SOAP content into a variable --->
<cfsavecontent variable="soapContent">
<cfoutput>
<cfloop collection = #soapData.headers# item = "http_item">
#http_item#: #StructFind(soapData.headers, http_item)# #chr(10)##chr(13)#
</cfloop>
request_method: #soapData.method# #chr(10)##chr(13)#
server_protocol: #soapData.protocol# #chr(10)##chr(13)#
http_content --- #chr(10)##chr(13)#
#toString(soapData.content)#
</cfoutput>
</cfsavecontent>
<!--- Save file to flat file --->
<cffile action = "write"
file = "#expandPath('../')#logs/#dateFormat(now(),'dd-mm-yyyy')#_#timeFormat(now(),'HHmmss')#.txt"
output = "#soapContent#">
Теперь я представляю ответ как полный XML-ответ SOAP, содержащий тело как встроенный XML с требуемым STATUSCODE (см. ниже).
<cfsavecontent variable="strResponse">
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
<SOAPENV:Body>
<ns1:processResponse xmlns:ns1="urn:TripFlow" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<STATUSLVL>00</STATUSLVL>
</ns1:processResponse>
</SOAP-ENV:Body>
</SOAPENV:Envelope>
</cfsavecontent>
<!--- Strip all whitespace between tags --->
<cfset strResponse = trim(ReReplaceNoCase(strResponse,'(>[\s]*<)','><','ALL'))>
<!--- Output the XML response to the soap service --->
<cfoutput>#strResponse#</cfoutput>
Вышеупомянутый ответ вызывает ошибку, потому что служба SOAP требует, чтобы ответ отправлялся, ссылаясь на сообщение тела, как вложение, точно такое же, как из документации:
HTTP/1.1 200 OK
Date: Thu, 01 Apr 2010 09:30:25 GMT
Server: Jetty/5.1.4 (Windows XP/5.1 x86 java/1.5.0_15
Content-Type: multipart/related; boundary=soaptestserver; type="text/xml"; start="<theenvelope>"
SOAPAction: ""
Content-Length: 796
Connection: close
--soaptestserver
Content-ID: <theenvelope>
Content-Transfer-Encoding: 8bit
Content-Type: text/xml; charset=utf-8
Content-Length: 442
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAPENV="
http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"><SOAPENV:
Body><ns1:processResponse xmlns:ns1="urn:TripFlow" SOAPENV:
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><message
href="cid:thecontentmessage"/></ns1:processResponse></SOAP-ENV:Body></SOAPENV:
Envelope>
--soaptestserver
SOAP Interface
www.travelsolutions.com 123
travel solutions online V14.0 External System Integration
Content-ID: <thecontentmessage>
Content-Transfer-Encoding: 8bit
Content-Type: text/xml; charset=utf-8
Content-Length: 65
<?xml version="1.0" encoding="UTF-8"?><STATUSLVL>00</STATUSLVL>
--soaptestserver--
Любая помощь будет очень признательна, поскольку я действительно ударяю головой о стену на этом. Спасибо!
Ответы
Ответ 1
Прошло некоторое время с тех пор, как я работал с ColdFusion. Последнее, что я помню, не предоставило привязку для отправки приложения SOAP. Я решил эту проблему, написав пользовательский тег CFX с Java, который сделал это для меня. Весь вызов SOAP должен пройти через тег.
Библиотека Java, на которую вы хотите посмотреть, если вы решите сделать это, javax-ws. Вам также необходимо выяснить, должен ли сервисный вызов использовать MTOM.
Извините, что это не прямое решение, но это то, что мне пришлось делать с CF несколькими версиями.
Ответ 2
Когда я взаимодействую с SOAP-сервисами, я обычно использую что-то похожее на это. Он вообще работает. Обратите внимание на то, что у меня есть текст, который вам нужно заменить, с соответствующими значениями для стороннего поставщика.
<cfsavecontent variable="soap">
<?xml version="1.0" encoding="UTF-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<ns1:processResponse xmlns:ns1="urn:TripFlow" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<statuslvl>00</statuslvl>
</ns1:processResponse>
</soapenv:Body>
</soapenv:Envelope>
</cfsavecontent>
<!--- Invoke web service to send message--->
<cfhttp url="http://3rd-party-url-here" method="post" timeout="10">
<cfhttpparam type="header" name="content-type" value="text/xml" />
<cfhttpparam type="header" name="SOAPAction" value="""3rd-party-method-name-here""" />
<!---<cfhttpparam type="header" name="accept-encoding" value="no-compression" /> sometimes this is needed --->
<cfhttpparam type="header" name="content-length" value="#len(soap)#" />
<cfhttpparam type="header" name="charset" value="utf-8" />
<cfhttpparam type="xml" name="message" value="#trim(soap)#" />
</cfhttp>