Sending a SOAP request using Savon - web-services

I am having trouble with a SOAP request I would like to send using Savon.
I get the following error:
{:fault=> {:faultcode=>"soap:Client", :faultstring=>
"Unmarshalling Error: unexpected element (uri:\"\", local:\"api\"). Expected elements are <{}Eft>,<{}Customer>,<{}Safekey>,<{}Fraud>,<{}Customfield>,<{}BankTransfer>,<{}Creditcard>,<{}Basket>,<{}TransactionType>,<{}Ebucks>,<{}Loyalty>,<{}Soulstace>,<{}TransactionRecord>,<{}AdditionalInformation>,<{}Api>,<{}Autopay>,<{}Stage>,<{}Globalpay> "}}
My .rb file looks like this:
require 'savon'
require 'pp'
require 'rubygems'
client = Savon.client({
:wsdl => "https://staging.payu.co.za/service/PayUAPI?wsdl",
:pretty_print_xml => true,
:log_level => :debug,
:wsse_auth => ["Staging Integration Store 2", "XSWYgMUA"],
})
request_msg = {
:Api => "ONE_ZERO",
:Safekey => "{826BD3C4-9663-48B0-804B-044BAA6A57F1}",
:TransactionType => "PAYMENT",
:AdditionalInformation => {
:merchantReference => "mercRef_1350046243",
:cancelUrl => "http://example.com/cancel-page/",
:returnUrl => "http://example.com/return/",
:supportedPaymentMethods => "CREDITCARD"
},
:Customer => {
:email => "john#doe.com",
:firstName => "John",
:lastName => "Doe",
:merchantUserId => 1350046243
},
:Basket => {
:amountInCents => 100,
:currencyCode => "ZAR",
:description => "Basket description comes here"
}
}
begin
set_transaction = client.call(:set_transaction) do
message(request_msg)
end
rescue Savon::SOAPFault => error
pp error.to_hash
end
And here is the working SOAP request XML (Tested in SoapUI) I would like to send using the above code:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soap.api.controller.web.payjar.com/" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<SOAP-ENV:Header>
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-9" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>Staging Integration Store 1</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">78cXrW1W</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:setTransaction>
<Api>ONE_ZERO</Api>
<Safekey>{45D5C765-16D2-45A4-8C41-8D6F84042F8C}</Safekey>
<TransactionType>PAYMENT</TransactionType>
<AdditionalInformation>
<merchantReference>mercRef_1350046243</merchantReference>
<cancelUrl>http://example.com/cancel-page/</cancelUrl>
<returnUrl>http://example.com/return/</returnUrl>
<supportedPaymentMethods>CREDITCARD</supportedPaymentMethods>
</AdditionalInformation>
<Customer>
<email>john#doe.com</email>
<firstName>John</firstName>
<lastName>Doe</lastName>
<merchantUserId>1350046243</merchantUserId>
</Customer>
<Basket>
<amountInCents>100</amountInCents>
<currencyCode>ZAR</currencyCode>
<description>Basket description comes here</description>
</Basket>
</ns1:setTransaction>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Related

"Missing <soap-env:Header> in <soap-env:Envelope>" - Sabre Webservice Consumer in Mule 4

Attempting to call Sabre web service but getting the above SOAP error. Clearly the header is not missing. Stumped at this point.
Incoming params are passed into Transform Message processor and payload is converted to XML and passed into Web Service Consumer to make external call. The Consumer config uses the WSDL provided by Sabre.
I'm sure I'm missing something simple. Any help is appreciated.
Dataweave code in Transform processor:
%dw 2.0
output application/xml
ns soapenv http://schemas.xmlsoap.org/soap/envelope/
ns eb http://www.ebxml.org/namespaces/messageHeader
ns wsse http://schemas.xmlsoap.org/ws/2002/12/secext
---
{
soapenv#Envelope: {
soapenv#Header:
eb#MessageHeader: {
eb#From: {
eb#PartyId: {}
},
eb#To: {
eb#PartyId: {}
},
eb#CPAId: "XX",
eb#ConversationId: vars.responseVars.conversationId,
eb#Service: "DisplayInventoryRecordLLSRQ",
eb#Action: "DisplayInventoryRecordLLSRQ",
eb#MessageData: {
eb#MessageId: {},
eb#Timestamp: {},
eb#TimeToLive: {}
},
wsse#Security: {
wsse#BinarySecurityToken: vars.responseVars.securityToken
}
},
soapenv#Body: {
DisplayInventoryRecordRQ: {
POS: {
Source: {
PseudoCityCode: vars.requestVars.origin
},
FlightNumber: vars.requestVars.flightNumber,
DepartureDate: vars.requestVars.departureDate,
DepartureAirport: {
LocationCode: "ALL"
},
ArrivalAirport: {
LocationCode: vars.requestVars.destination,
CodeContext: "IATA"
}
}
}
}
}
}
XML passed to Consumer:
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<eb:MessageHeader xmlns:eb="http://www.ebxml.org/namespaces/messageHeader">
<eb:From>
<eb:PartyId/>
</eb:From>
<eb:To>
<eb:PartyId/>
</eb:To>
<eb:CPAId>XX</eb:CPAId>
<eb:ConversationId>### Masked ###</eb:ConversationId>
<eb:Service>DisplayInventoryRecordLLSRQ</eb:Service>
<eb:Action>DisplayInventoryRecordLLSRQ</eb:Action>
<eb:MessageData>
<eb:MessageId/>
<eb:Timestamp/>
<eb:TimeToLive/>
</eb:MessageData>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:BinarySecurityToken>### Masked ###</wsse:BinarySecurityToken>
</wsse:Security>
</eb:MessageHeader>
</soapenv:Header>
<soapenv:Body>
<DisplayInventoryRecordRQ>
<POS>
<Source>
<PseudoCityCode>XXX</PseudoCityCode>
</Source>
<FlightNumber>###</FlightNumber>
<DepartureDate>2020-03-05</DepartureDate>
<DepartureAirport>
<LocationCode>ALL</LocationCode>
</DepartureAirport>
<ArrivalAirport>
<LocationCode>XXX</LocationCode>
<CodeContext>IATA</CodeContext>
</ArrivalAirport>
</POS>
</DisplayInventoryRecordRQ>
</soapenv:Body>
</soapenv:Envelope>
Error Message:
ERROR 2020-03-05 13:01:25,188 [[MuleRuntime].io.10: [proc-ix-action-server-app].main-flow.BLOCKING #72b2e7e6] [event: 1594fcb1-5f1c-11ea-b89c-8c04ba8b4cea] org.mule.runtime.core.internal.exception.OnErrorContinueHandler:
********************************************************************************
Message : Missing <soap-env:Header> in <soap-env:Envelope>.
Error type : WSC:SOAP_FAULT
Element : get-inventory-subflow/processors/0/processors/1 # proc-ix-action-server-app:main.xml:133 (Consume)
Element XML : <wsc:consume operation="DisplayInventoryRecordRQ" doc:name="Consume" doc:id="fbeaeba3-f04c-4d40-bf87-bd63c1a8ac34" config-ref="Web_Service_Consumer_Config"></wsc:consume>
Working Postman call for comparison:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Header>
<eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:version="1.0">
<eb:From>
<eb:PartyId />
</eb:From>
<eb:To>
<eb:PartyId />
</eb:To>
<eb:CPAId>XX</eb:CPAId>
<eb:ConversationId>### Masked ###</eb:ConversationId>
<eb:Service>DisplayInventoryRecordLLSRQ</eb:Service>
<eb:Action>DisplayInventoryRecordLLSRQ</eb:Action>
<eb:MessageData>
<eb:MessageId />
<eb:Timestamp />
<eb:TimeToLive />
</eb:MessageData>
</eb:MessageHeader>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:BinarySecurityToken valueType="String" EncodingType="wsse:Base64Binary">### Masked ###</wsse:BinarySecurityToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<DisplayInventoryRecordRQ TimeStamp="2010-11-30T15:30:00-06:00" Version="1.2.1" xmlns="http://webservices.sabre.com/sabreXML/2003/07" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<POS>
<Source PseudoCityCode="XXX"/>
</POS>
<FlightNumber>##</FlightNumber>
<DepartureDate>2020-03-05</DepartureDate>
<DepartureAirport LocationCode="XXX"/>
<ArrivalAirport LocationCode="XXX" CodeContext="IATA"/>
</DisplayInventoryRecordRQ>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
You should pass the body contents only as the payload, not the soap elements. Those are added by the Web Service Consumer.

How to set header to call soap service in mulesoft

I want to call one soap service through mulesoft.
To attach header to soap request body I used these links -Mule 3.7. Add custom SOAP header to web-service-consumer. As mentioned in this link, I have added "Message Properties" component before "Web Service Consumer", but I am getting below exception -
com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "soapenv" (for attribute "actor")
Also I tried it using Property component as mentioned here - https://dzone.com/articles/working-with-headers-in-mule-flows
Still I am not able to hit soap service. Is there any other way to add header to soap request body?
Header that i want to add to my soap request -
<wsse:Security soapenv:actor="AppID" soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>Pilot\ABCD</wsse:Username>
<wsse:Password wsse:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">yt15#58</wsse:Password>
</wsse:UsernameToken>
--Update- My code-
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:ws="http://www.mulesoft.org/schema/mule/ws" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ws http://www.mulesoft.org/schema/mule/ws/current/mule-ws.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd">
<ws:consumer-config name="Web_Service_Consumer_2" wsdlLocation="https://soa.abc.com/abcd_v4_0?wsdl" service="abcdService_vs0" port="xyz_Internal" serviceAddress=""https://soa.abc.com:56655/abcd_v4_0" doc:name="Web Service Consumer">
<ws:security>
<ws:wss-username-token username="user" password="password" passwordType="TEXT"/>
</ws:security>
</ws:consumer-config>
<sub-flow name="tempSub_Flow">
<set-property propertyName="soap.Security" value="<wsse:Security soapenv:actor="AppID" soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/></wsse:Security>" doc:name="Property"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 urn:abc.com:schemas:gfr:a:b:service:2014-01-10
---
{
ns0#addTransaction:{
ns0#aTransaction: {
ns0#transactionCode: "xyz",
ns0#methodCode: "abc",
ns0#amount: flowVars.amount,
ns0#effectiveDate: now as :string {format: "yyyy-MM-dd"}
}
}
}]]></dw:set-payload>
</dw:transform-message>
<ws:consumer config-ref="Web_Service_Consumer_2" operation="addEftTransaction" doc:name="Web Service Consumer"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
%namespace ns0 urn:abc.com:schemas:gfr:a:b:service:2014-01-10
---
payload.ns0#addTransactionResponse.ns0#transactionNumber
]]></dw:set-payload>
</dw:transform-message>
</sub-flow>
</mule>
--- UPDATE ---
Two parts to the answer really, for the direct question of how to add SOAP headers, it looks like you might have missed declaring the namespace of soapenv for the Security element you were adding. For example, the below code should work for adding the "Security" header to the SOAP Envelope. The whole XML element must be defined, including any namespaces it uses.
<set-property propertyName="soap.Security" value="<wsse:Security soapenv:actor="AppID" soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><wsse:UsernameToken><wsse:Username>Pilot\ABCD</wsse:Username><wsse:Password wsse:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">yt15#58</wsse:Password></wsse:UsernameToken></wsse:Security>" doc:name="Set soap.Security"/>
That looks pretty unattractive though, and since you are adding a username/password security header then you probably want to add this directly into the security element of the Web Service Consumer configuration itself:
<ws:consumer-config name="WSConfig" wsdlLocation="MyService.wsdl" service="MyService" port="MyPort" serviceAddress="https://example.com" doc:name="Web Service Consumer">
<ws:security>
<ws:wss-username-token username="Pilot\ABCD" password="yt15#58" passwordType="TEXT"/>
</ws:security>
</ws:consumer-config>
The issue with the above is that it won't add the soapenv:actor="appId" attribute.
It looks like the security configuration on the WS consumer will overwrite the actor attribute. The below code mostly works on Mule 3.8 and uses the sample WSDL found here: https://github.com/skjolber/mockito-soap-cxf/tree/master/src/test/resources/wsdl
The first flow builds the request to the SOAP web service, the second flow just receives the request made by the first flow and logs it.
<mule xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata"
xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw"
xmlns:ws="http://www.mulesoft.org/schema/mule/ws"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ws http://www.mulesoft.org/schema/mule/ws/current/mule-ws.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd">
<ws:consumer-config name="BankCustomerService_WS_Consumer" wsdlLocation="BankCustomerService.wsdl" service="BankCustomerService" port="BankCustomerServicePort" serviceAddress="http://localhost:8778/services/bankCustomer" doc:name="Web Service Consumer">
<ws:security>
<ws:wss-username-token username="user" password="password" passwordType="TEXT"/>
</ws:security>
</ws:consumer-config>
<http:listener-config name="HTTP_TestListener" host="0.0.0.0" port="8092" doc:name="HTTP Listener Configuration"/>
<http:listener-config name="HTTP_WebServiceStub" host="0.0.0.0" port="8778" doc:name="HTTP Listener Configuration"/>
<flow name="soapsandboxFlow">
<http:listener config-ref="HTTP_TestListener" path="/soap" doc:name="HTTP"/>
<set-property propertyName="soap.Security" value="<wsse:Security soapenv:actor="AppID" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" />" doc:name="Set soap.Security"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 http://example.bank.skjolber.github.com/v1
---
{
ns0#getAccountsRequest: {
ns0#customerNumber: 987654321,
ns0#certificate: 1234
}
}]]></dw:set-payload>
</dw:transform-message>
<ws:consumer config-ref="BankCustomerService_WS_Consumer" operation="getAccounts" doc:name="Web Service Consumer"/>
</flow>
<flow name="soapsandboxFlow1">
<http:listener config-ref="HTTP_WebServiceStub" path="services/bankCustomer" doc:name="HTTP"/>
<logger message="#[message.payloadAs(String)]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
Running a simple GET request to localhost:8092 creates a static web service request and sends that to through the WS Consumer Component. The logger in the stub prints out the entire SOAP envelope, which as shown below includes the security header, but not the actor attribute:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken-CA524029E5DEDE6E3715320371056746">
<wsse:Username>user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<ns0:getAccountsRequest xmlns:ns0="http://example.bank.skjolber.github.com/v1">
<ns0:customerNumber>987654321</ns0:customerNumber>
<ns0:certificate>1234</ns0:certificate>
</ns0:getAccountsRequest>
</soap:Body>
</soap:Envelope>
I will do a bit more research to see if I can include the actor attribute in the security header. As this is a standard attribute I it should be possible. I will update this answer when I can.
Johnson.

HTTP Receiver. Error while parsing http request for processing:

logstash output:
output{
if [type]=="nxlog-json"{
http {
codec => json
http_method => "post"
url=>"http://192.168.1.112:9763/endpoints/test"
}
}
}
HTTP Receiver config:
<?xml version="1.0" encoding="UTF-8"?>
<eventReceiver name="test" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="http">
<property name="basicAuthEnabled">false</property>
<property name="transports">all</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="teststream" version="1.0.0"/>
</eventReceiver>
ERROR in log:
ERROR {org.wso2.carbon.event.input.adapter.http.HTTPMessageServlet} -
Error while parsing http request for processing: Path 'event' not
found in the current context:
How to fix it?
WSO2 CEP Version 4.2.0
Solved this issue by wrapping json object via "event":{} as follows.
jsonObject={
"event": {
"payloadData": {
"companyID":companyID,
"activityID":activityID
}
}
}

How can I resolve "unexpected encoding style" using Savon Gem with Ruby on Rails

I am getting the following error when accessing a WSDL SOAP server:
{:error=>true, :message=>"Savon::SOAPFault: (env:Client) JAXRPCTIE01: caught exception while handling request: unexpected encoding style: expected=http://schemas.xmlsoap.org/soap/encoding/, actual="}
I went to soapclient.com to figure out what it's looking for.
Here is the error message I'm receiving.
Here is the code I'm using to connect to the SOAP client:
my_hash_of_stuff = {
zipcode: d_zip,
country: country
}
wsdl = 'http://my.yrc.com/dynamic/national/WebServices/YRCZipFinder_V1.wsdl'
client = Savon.client(wsdl: wsdl,
logger: Rails.logger,
log_level: :debug,
log: true,
pretty_print_xml: true,
env_namespace: :'soap-env',
strip_namespaces: true
)
response = client.call(:lookup_zip, message: my_hash_of_stuff)
print response.to_hash
Here's a copy of my log output so you can see what's happening.
This appears to be what the SOAP request should look like according to soapclient.com (if i'm understanding it correctly).
This is what I am sending.
I've been fighting with it all day and I'm sure it's probably a combination of my ignorance and something simple that i'm missing. Hopefully you guys might be able to help?
EDIT 05/25/2016:
So, looking at this again today, here's the log showing the request that savon is making:
HTTPI GET request to my.yrc.com (net_http)
SOAP request: http://my.yrc.com/dynamic/national/webservice/YRCZipFinder_V1
SOAPAction: "http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl/lookupCity", Content-Type: text/xml;charset=UTF-8, Content-Length: 417
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<tns:lookupCity>
<zipCode>84101</zipCode>
<country>USA</country>
</tns:lookupCity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here's what a correct one looks like. I got this from the existing php app and tested it in Postman to verify that it works:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://my.yrc.com/national/WebServices/YRCZipFinderMessages_V1.xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:lookupCity>
<lookupCityRequest xsi:type="ns2:YRCLookupCityRequest">
<zipCode xsi:type="xsd:string">84101</zipCode>
<country xsi:type="ns2:CountryCode">USA</country>
</lookupCityRequest>
</ns1:lookupCity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
UPDATE:
After some more hacking, I have my request looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://my.yrc.com/national/WebServices/YRCZipFinderMessages_V1.xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<tns:lookupCity lookupCityRequest="ns2:YRCLookupCityRequest">
<zipCode>84101</zipCode>
<country>USA</country>
</tns:lookupCity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I need to get lookupCityRequest to move inside lookupCity instead of being an attribute of lookupCity, however. Testing it in Postman, that appears to be the only stumbling block left to hurdle.
You can use the special :attribute!symbol to assign additional attributes. That's a functionality from Nokogiri which Savon uses to build XML.
require 'savon'
my_hash_of_stuff =
{ zipcode: "99103",
country: 'US',
attributes!: { :country => { 'xsi:type' => 'ns2:YRCLookupCityRequest'},
:zipcode => { 'xsi:type' => 'ns2:YRCLookupCityRequest' }}
}
wsdl = 'http://my.yrc.com/dynamic/national/WebServices/YRCZipFinder_V1.wsdl'
client = Savon.client(wsdl: wsdl,
# logger: Rails.logger,
log_level: :debug,
log: true,
pretty_print_xml: true,
env_namespace: :'soap-env',
strip_namespaces: true
)
response = client.call(:lookup_zip,
message: my_hash_of_stuff)
print response.to_hash
If nothing works and you're desperate enough then you can still create your very own XML and use xml: instead of message:.

How to parse SOAP response using FLEX

My Flex application properly call a web service but it does not populate the drop down box.
Based on my researches the problem is with the namespaces, but still not sure how to solve it.
Once I run the application the drop down box is empty.
My java code
package com.Services;
import com.classes.*;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebResult;
#WebService (name="Hellos",
targetNamespace="http://localhost:8081/Mywebservice2/services/Hellos")
public class Hellos {
#WebMethod
public #WebResult (name="customers",partName="customers") Customer[] mycustomers()
{
System.out.println("Retriving customers....");
Customer[] cus = new Customer[2];
cus[0] = new Customer("Jack", 28);
cus[1] = new Customer("Ben", 29);
return cus;
}
}
The network monitor feature of the flex application shows the response is as following
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Thu, 10 Jan 2013 04:23:55 GMT
<?xml version="1.0" encoding="utf-8"?>
<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:Body>
<mycustomersResponse xmlns="http://Services.com">
<mycustomersReturn>
<age>28</age>
<name>Jack</name>
</mycustomersReturn>
<mycustomersReturn>
<age>29</age>
<name>Ben</name>
</mycustomersReturn>
</mycustomersResponse>
</soapenv:Body>
</soapenv:Envelope>
my flex code is as following
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
protected function
dropDownList2_creationCompleteHandler(event:FlexEvent):void
{
mycustomersResult2.token = hellos.mycustomers();
}
]]>
</fx:Script>
<fx:Declarations>
<hellos:Hellos id="hellos" fault="Alert.show(event.fault.faultString + '\n'
+ event.fault.faultDetail)"
showBusyCursor="true"/>
<s:CallResponder id="mycustomersResult2"/>
</fx:Declarations>
<s:FormItem label="Label">
<s:DropDownList id="dropDownList2"
creationComplete="dropDownList2_creationCompleteHandler(event)"
labelField="age">
<s:AsyncListView list="{mycustomersResult2.lastResult}"/>
</s:DropDownList>
</s:FormItem>
When I change
<s:AsyncListView list="{mycustomersResult2.lastResult}"/>
to
<s:AsyncListView list="
{mycustomersResult2.lastResult.mycustomersResponse.mycustomersReturn}"/>
it gives the following error
Error: Unknown Property: 'mycustomersResponse'.
at mx.collections::ListCollectionView/http://www.adobe.com/2006/actionscript/flash/proxy::getProperty()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:870]
at mx.binding::PropertyWatcher/updateProperty()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\PropertyWatcher.as:338]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.binding::Watcher/wrapUpdate()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\Watcher.as:192]
at mx.binding::PropertyWatcher/updateParent()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\PropertyWatcher.as:239]
at mx.binding::Watcher/updateChildren()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\Watcher.as:138]
at mx.binding::PropertyWatcher/updateProperty()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\PropertyWatcher.as:347]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.binding::Watcher/wrapUpdate()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\Watcher.as:192]
at mx.binding::PropertyWatcher/eventHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\binding\PropertyWatcher.as:375]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.rpc::CallResponder/set lastResult()
at mx.rpc::CallResponder/result()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\CallResponder.as:120]
at mx.rpc::AsyncToken/http://www.adobe.com/2006/flex/mx/internal::applyResult()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\AsyncToken.as:239]
at mx.rpc.events::ResultEvent/http://www.adobe.com/2006/flex/mx/internal::callTokenResponders()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\events\ResultEvent.as:207]
at mx.rpc::AbstractOperation/http://www.adobe.com/2006/flex/mx/internal::dispatchRpcEvent()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\AbstractOperation.as:244]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::resultHandler()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:318]
at mx.rpc::Responder/result()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\Responder.as:56]
at mx.rpc::AsyncRequest/acknowledge()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:84]
at DirectHTTPMessageResponder/completeHandler()[E:\dev\4.5.1\frameworks\projects\rpc\src\mx\messaging\channels\DirectHTTPChannel.as:451]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
It seems like problem with namespace for response xml format:
<mycustomersResponse xmlns="http://Services.com">
Just write anywhere in you code :
namespace ns = "http://Services.com";
use namespace ns;
I have written demo with given xml:
var xml: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:Body>
<mycustomersResponse xmlns="http://Services.com">
<mycustomersReturn>
<age>28</age>
<name>Jack</name>
</mycustomersReturn>
<mycustomersReturn>
<age>29</age>
<name>Ben</name>
</mycustomersReturn>
</mycustomersResponse>
</soapenv:Body>
</soapenv:Envelope>
namespace ns = "http://Services.com";
use namespace ns;
namespace ns_soapenv = "http://schemas.xmlsoap.org/soap/envelope/";
use namespace ns_soapenv;
trace(xml.Body.mycustomersResponse.mycustomersReturn.length()); //output 2
It is parsed good. Hope it would helpful.
You don't have to parse it, the WebService class does it for you.
<s:WebService result=" soapResultHandler(event) ">
<!-- do stuff here -->
</s:WebService>
<fx:Script>
<![CDATA[
private function soapResultHandler( e:ResultEvent ):void {
//do stuff to e.result in here
}
]]>
</fx:Script>
The ResultEvent.result object is the XML automatically parsed into a single dynamic Object. You can easily loop through that to get whatever details you need. It is worth noting that if a single level of the XML document has multiple instances of the same tag name, there will be an ArrayCollection (not Array, mind) rather than a series of those objects.
See the ResultEvent#result LiveDocs