Namespace prefix getting changed from request to response - wsdl

I developed one service using websphere application server and Rational application developer(RAD) . I am using SOAP UI to unit test my service. The service is well deployed and getting the accurate results but the problem is in the namespace prefixes.prefixes of response i am getting is different from the prefixes of request namespaces. i.e. if request having namespaces defined as common, domain etc..i am getting response having namespaces as a,b,c ..
the request is as goes here...
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tic="http://www.trrt.com/pos/TicketRemark_v1" xmlns:dom="http://www.tport.com/pos//Domain" xmlns:com="http://www.tralport.com/pos//Common">
<soapenv:Header/>
<soapenv:Body>
<tic:RetrrksRequest Version="1" >
<dom:TicketDocument TicketNbr="6000001"/>
</tic:RetrrksRequest>
</soapenv:Body>
</soapenv:Envelope>
the response is...
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<c:RetrrksResponse Version="1" TimeStamp="2012-08-23T14:15:59.000" xmlns:a="http://www.trrt.com/pos/viewtrip/schema/CommonTypes_v1" xmlns:b="http://www.trport.com/pos/viewtrip/schema/DomainTypes_v1" xmlns:c="http://www.travt.com/pos/viewtrip/schema/TicketRemarksServices_v1">
<a:Success/>
<b:TicketDocument TicketDocumentNbr="6000000000001" TotalDocQuantity="7"/>
<b:BookiID CreateDateTime="2012-08-12T12:40:00.000" PurgeDate="2013-06-20" ID="ABCDEF">
</b:BookiID>
<b:FeeRemarks>
<b:Remark Type="3000">remark text</b:Remark>
</b:FeeRemarks>
</c:RetrirksResponse>
</soapenv:Body>
</soapenv:Envelope>

This is not a problem. The namespace prefix may be arbitrary, so long as it references the correct namespace. One should not depend on the particular choice of a namespace prefix. Any code that does rely on a choice of prefix will likely suffer interoperability problems.

Related

XSD validation fails with UndeclaredPrefix when using AxiomSoapMessageFactory in Spring WS

I'm building a contract-first SOAP web service with spring-ws 2.2.3. My XML Schema uses extensions, leading to xsi:type= attributes in the XML requests. Since some respones can be very large (30MB), I'm using a AxiomSoapMessageFactory instead of the default SaajSoapMessageFactory, as suggested in the Spring WS docs. I validate incoming requests with a PayloadValidatingInterceptor:
PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
interceptor.setSchema(new ClassPathResource("format-service.xsd"));
interceptor.setValidateRequest(true);
interceptor.setValidateResponse(false);
My problem is that I get spurious validation errors, depending on where in the XML the namespace is declared: if it's declared in the payload, then everything works fine:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<sch:formatRequest xmlns:sch="http://example.com/springws/extension/schema">
<sch:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="sch:currencyType">
<sch:amount>1000</sch:amount>
<sch:currency>EUR</sch:currency>
</sch:value>
</sch:formatRequest>
</soapenv:Body>
</soapenv:Envelope>
But as soon as I move the sch namespace declaration up to the Envelope:
<soapenv:Envelope xmlns:sch="http://example.com/springws/extension/schema" ...>
validation fails and I receive a SOAP Fault:
<faultcode>soapenv:Client</faultcode>
<faultstring xml:lang="en">Validation error</faultstring>
<detail>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-elt.4.1: The value 'sch:currencyType' of attribute 'http://www.w3.org/2001/XMLSchema-instance,type' of element 'sch:value' is not a valid QName.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-type.2: The type definition cannot be abstract for element sch:value.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-attribute.3: The value 'sch:currencyType' of attribute 'xsi:type' on element 'sch:value' is not valid with respect to its type, 'QName'.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-complex-type.2.1: Element 'sch:value' must have no character or element information item [children], because the type's content type is empty.</spring-ws:ValidationError>
</detail>
It appears like a bug in the AxiomSoapMessageFactory / Axiom implementation to me (namespace context is lost), as both requests validate fine when using the SaajSoapMessageFactory. Note that the validation only fails on the xsi:type= attribute. The same namespace is recognized correctly for elements.
I cannot use SaajSoapMessageFactory due to high memory consumption for large responses. I found similar problems described in the Spring forum and on SO, but no solution. Thanks for help!
The reason is that Spring-WS uses OMContainer#getXMLStreamReader(). Instead it should use OMContainer#getXMLStreamReader(boolean, OMXMLStreamReaderConfiguration) and set the preserveNamespaceContext property to true in the OMXMLStreamReaderConfiguration object.
You should file a bug for Spring-WS, or even better, fix the issue and submit a pull request.

savon (SOAP:Server) No handlers could be found for unmarshalling the SOAP body payload

Objective
Build Soap call via savon v2
What I tried :
my soap call RQ , this is what given in the documentation
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://www.opentravel.org/OTA/2003/05">
<soapenv:Header/>
<soapenv:Body>
<OTA_AirLowFareSearchRQ TimeStamp="2012-04-18T07:30:42.663Z" Target="Production" Version="1.0" PrimaryLangID="en" AltLangID="en" RetransmissionIndicator="false" xmlns="http://www.opentravel.org/OTA/2003/05">
<POS>
<Source ISOCountry="ZA" ISOCurrency="ZAR" DisplayCurrency="ZAR" DisplayRate="1.0" FirstDepartPoint="CPT" FinalDestinationPoint="JNB">
<RequestorID Type="Company" ID="website" ID_Context="ts" TSAffiliateID="<AFFILIATE_ID>" MessagePassword="<AFFILIATE_PASSWORD>">
<CompanyName><AFFILIATE_ID></CompanyName>
</RequestorID>
</Source>
</POS>
<OriginDestinationInformation RefNumber="0">
<DepartureDateTime>2012-07-26T00:00:00CAT</DepartureDateTime>
<OriginLocation LocationCode="CPT" CodeContext="iata"/>
<DestinationLocation LocationCode="JNB" CodeContext="iata"/>
</OriginDestinationInformation>
<OriginDestinationInformation RefNumber="1">
<DepartureDateTime>2012-07-29T00:00:00CAT</DepartureDateTime>
<OriginLocation LocationCode="JNB" CodeContext="iata"/>
<DestinationLocation LocationCode="CPT" CodeContext="iata"/>
</OriginDestinationInformation>
<TravelPreferences>
<FlightTypePref FlightType="Nonstop" DirectAndNonStopOnlyInd="true"/> <!-- This line is optional – include to filter direct flights only -->
<CabinPref Cabin="Economy"/>
</TravelPreferences>
<TravelerInfoSummary>
<AirTravelerAvail>
<PassengerTypeQuantity Code="7" Quantity="0"/>
<PassengerTypeQuantity Code="8" Quantity="0"/>
<PassengerTypeQuantity Code="9" Quantity="0"/>
<PassengerTypeQuantity Code="10" Quantity="1"/>
</AirTravelerAvail>
</TravelerInfoSummary>
</OTA_AirLowFareSearchRQ>
</soapenv:Body>
</soapenv:Envelope>
my Target Url : eg: http://www.example.com?wsdl
operation name : search
#client = Savon.client(wsdl: ' http://www.example.com?wsdl')
#client.call(:search, message: { 'RefNumber' => '1','DepartureDateTime'=>'2014-09-26T00:00:00CAT','ArrivalDateTime'=>'2012-10-26T00:00:00CAT','OriginLocation'=>'CPT','DestinationLocation'=>'JNB' })
what i am getting :
(SOAP:Server) No handlers could be found for unmarshalling the SOAP body payload
The Soap call i built is correct or i have to build the entire xml of Soap body ?
Any help is appreciated !!
My standard answer:
download SoapUI
build a valid SOAP request.
make sure it works
then replicate the request with Ruby/Savon
if it still doesn't work, ask again

Trying to build SOAP Request with Savon?

I am trying to hit a SOAP Service from Ruby on Rails - from SOAP UI I can hit it fine and the request XML is as below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:mun="http://schemas.datacontract.org/2004/07/MyExternalService.Map" xmlns:mun1="http://schemas.datacontract.org/2004/07/MyExternalService.Common.Map">
<soapenv:Header/>
<soapenv:Body>
<tem:GetInformationsForCoordinates>
<!--Optional:-->
<tem:coordReq>
<!--Optional:-->
<mun:Coordinates>
<!--Zero or more repetitions:-->
<mun:Coordinate>
<!--Optional:-->
<mun:Id>1</mun:Id>
<!--Optional:-->
<mun:QualityIndex>90</mun:QualityIndex>
<!--Optional:-->
<mun:X>-110.5322</mun:X>
<!--Optional:-->
<mun:Y>35.2108</mun:Y>
</mun:Coordinate>
</mun:Coordinates>
</tem:coordReq>
<!--Optional:-->
<tem:analysisTypes>
<!--Zero or more repetitions:-->
<mun:AnalysisType>Additional</mun:AnalysisType>
</tem:analysisTypes>
</tem:GetInformationsForCoordinates>
</soapenv:Body>
</soapenv:Envelope>
If I copy that exact XML into a Ruby string with request = %q(XML STRING) into savon and use the method and then in Savon call the following:
response = client.call(:get_info, xml: request)
It works as expected and I get my response - however in reality I want to be just passing the parameters to Savon. So far I have tried the following:
coordinate = { Id: '1', X: -110.5322, Y: 35.2108, QualityIndex: 90 }
coordinates = {Coordinates: [coordinate] }
coordinateReq = {coordReq: {coordinates: coordinates} }
response = client.call(:get_informations_for_coordinates, message: coordinateReq)
This fails and if I look at the XML I am sending it is below:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://tempuri.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<tns:GetInformationsForCoordinates>
<coordReq>
<coordinates>
<coordinates>
<Id>1</Id>
<X>-110.5322</X>
<Y>35.2108</Y>
<QualityIndex>90</QualityIndex>
</coordinates>
</coordinates>
</coordReq>
</tns:GetInformationsForCoordinates>
</env:Body>
</env:Envelope>
In comparison to what is sent from SOAP UI I am missing the xmlns:mum namespace - is there anyway I can add it my request so that it is added to each parameter i.e. X, Y QualityIndex - also the tem which is similar to tns in my Savon call is added to the coordReq in SOAPUI but not in my Savon call - is there anyway I can add it?
Also I am having some difficulty in working out how to Build the analysisTypes and AnalysisType part of my request?
From the documentation:
Namespaces
If you don’t pass a namespace to Savon::Client#request, Savon will
register the target namespace (“xmlns:wsdl”) for you. If you did
pass a namespace, Savon will use it instead of the default one. For
example:
client.request :v1, :get_user
<env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:v1="http://v1.example.com">
<env:Body>
<v1:GetUser>
</env:Body>
</env:Envelope>
You can always set namespaces or overwrite namespaces set by Savon.
Namespaces are stored as a simple Hash.
# setting a new namespace
soap.namespaces["xmlns:g2"] = "http://g2.example.com"
# overwriting the "xmlns:wsdl" namespace
soap.namespaces["xmlns:wsdl"] = "http://ns.example.com"
Apparently, for Savon 2, setting multiple namespaces is impossible:
I found that is not possible (for now) to set multiple namespaces on
version 2 of Savon.
For now i migrate my application on Savon version 1 and it worked =)
To use multiple namespaces you put the following type of code in your client definition
...
:namespaces => {
"xmlns:v2" => "http://v2.example.com",
"xmlns:v1" => "http://v1.example.com" },
...

Number format exception in JIRA

I am getting number format exception while trying to get the issue details by using id.
RemoteIssue ri = jira.getIssueById(JIRAtoken, string.Format(IssueKey));
here jiratoken is string. But giving exception. Any one have any idea?
I had the same problem, using the SOAP Web Service API of JIRA (4).
I solved it by using getIssue instead of getIssueById. With getIssue, JIRA expects the key like MYPROJECT-3.
Now I send a request like this, and it works :
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://soap.rpc.jira.atlassian.com">
<soapenv:Header/>
<soapenv:Body>
<soap:getIssue soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<in0 xsi:type="xsd:string">MyAuthToken</in0>
<in1 xsi:type="xsd:string">MYPROJECT-1</in1>
</soap:getIssue>
</soapenv:Body>
</soapenv:Envelope>

Bad Request in SOAPUI

I am attempting to consume a web service using Delphi 2010 and Indy. To establish a usable SOAP stream to compare to the one created by my program, I am testing in SOAPUI. I am using a SOAP stream provided by the web service provider which also matches the SOAP stream specified in the WSDL file. I am getting an HTTP 400 (bad request) error from the service.
From what I can find online, it appears that receiving an HTTP 400 error indicates that your SOAP request is malformed and can not be read by the web service. I have tested my SOAP stream using XMLPad and the XML seems to be well formed. I suppose this may mean that something does not match its schema requirement. I will first check the schema description for the password in case that is expected to not be sent as plain text. What else should I be checking to eliminate an HTTP 400 error?
Here is my request (less username and password) in case it helps:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
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"
xmlns:xop="http://www.w3.org/2004/08/xop/include"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://wwww3.org/2001/XMLSchema-instance">
<soap:Header>
<wsa:Action>http://edd.ca.gov/SendTransmission</wsa:Action>
<wsa:MessageID>urn:uuid:5aa788dc-86e1-448b-b085-2d2743cf9f26</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://fsettestversion.edd.ca.gov/fsetproxy/fsetservice.asmx</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken">
<wsse:Username>#USERNAME#</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:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">O5QWht1bslLCX6KnlEypAA==</wsse:Nonce>
<wsu:Created>2012-02-29T22:32:38.250Z</wsu:Created>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="Timestamp-805a7373-335c-43b6-ba21-6596c4848dbf">
<wsu:Created>2012-02-22T15:41:42Z</wsu:Created>
<wsu:Expires>2012-02-22T15:46:42Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<SendTransmission xmlns="http://edd.ca.gov/">
<SendTransmissionRequest xmlns="http://www.irs.gov/a2a/mef/MeFTransmitterServiceWse.xsd">
<TransmissionDataList>
<Count>1</Count>
<TransmissionData>
<TransmissionId>123456789</TransmissionId>
<ElectronicPostmark>2012-02-22T07:41:42.2502206-08:00</ElectronicPostmark>
</TransmissionData>
</TransmissionDataList>
</SendTransmissionRequest>
<fileBytes>
<xop:Include href="cid:1.634654933022658454#example.org"/>
</fileBytes>
</SendTransmission>
</soap:Body>
</soap:Envelope>
There may be something else, but at the moment, I am suspicious of the wsse:UsernameToken. I downloaded the document at http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf and read it last night. It's written in fairly plain language and I feel like I understand what it is saying but it leaves me with a smaller question than the one I asked originally. This document proposes that you can use a plain text password in this format:
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>Zoe</wsse:Username>
<wsse:Password>IloveDogs</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
Or you can use a password digest. It defines a password digest like this:
Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
According to the reference, the format for a password digest would look like this:
<S11:Envelope xmlns:S11="..." xmlns:wsse="..." xmlns:wsu= "...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>NNK</wsse:Username>
<wsse:Password Type="...#PasswordDigest">
weYI3nXd8LjMNVksCKFV8t3rgHh3Rw==
</wsse:Password>
<wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
<wsu:Created>2003-07-16T01:24:32Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
This is not the format used in the example provided by the web service publisher. The plain text version in the reference does not use a nonce. The example message uses a nonce but calls for a plain text password. It appears to me that the use of a nonce without a password digest does not add any security to the message. It could be any random string of characters if there is no agreement for how it is to be created. Am I missing the point?
I know this must seem like a tedious undertaking, but I am hoping that by providing this here, maybe we can provide a little help to the next person coming along.
I too have come across this issue. The web service publisher (edd.ca.gov) responded by stating that the " value is required by the SOAP 1.2 standards" yet I find no valid support for that. It looks like we both are heading down the same path (FSET) and maybe we should team up and work together, two heads are better than one. I have found many mistakes within the example code and I too have yet get it to work.

Resources