i have implemented a webservice client that is used inside a webapplication (using Spring) and this client gets a response in which CXF bailsout and gives me an error message.
The error message is:
Server did not recognize the value of HTTP Header SOAPAction
I have found the problem but do not know what i can do to adjust my webservice response handling.
The xml response below works without any problems.
Works and is accepted ok!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bar="http://www.dummyurl.com/service-v1.0/">
<soapenv:Header/>
<soapenv:Body>
<bar:StartSessionResponse>
<result>1</result>
</bar:StartSessionResponse>
</soapenv:Body>
</soapenv:Envelope>
The service actually returns:
Fails and gives me an error!
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<StartSessionResponse xmlns="www.dummyurl.com/service-v1.0/">
<result xmlns="">1</result>
</StartSessionResponse>
</soap:Body>
</soap:Envelope>
The difference as far as i can see is in the placing of the
xmlns="www.dummyurl.com/service-v1.0/ element, in the success xml it is in the enveloppe, in the failed xml it is on the reponse method.
Is there a way that i can convince CXF to accept the response? Or is the service giving back an abnormal result?
The service is giving back a wrong response in the second case, assuming that the first response is proper.
In the first case "www.dummyurl.com/service-v1.0/" is the namespace of your elements - StartSessionResponse, result is not qualified with the namespace. In the second case, the StartSessionResponse has the same namespace as the first sample, but the result has a different namespace altogether, taking out xmlns="" for result will make the xml consistent.
Related
Web service provider has provided us(Client) a wsdl to use their service and consume data. Our requirement is, we just need specific node value called "CHASE", see below test data. We don't want to get all records of info and corresponding nodes in the response.
Here is an example that we have tested in SOAPUI tool. Please suggest and help us how can we frame the web service request technically from the URL provided(http://host:port/ValueMappingInService/ValueMappingInImplBean)? Is it at all possible to drill down the request and get specific response from client side?
Web service Request:-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:bas="http://sap.com/xi/BASIS">
<soapenv:Header/>
<soapenv:Body>
<bas:ValueMappingReadRequest>
<!--Optional:-->
<ReadContext>User</ReadContext>
<!--Zero or more repetitions:-->
<ValueMappingID>c44f541f-c8ac-11e8-86e5-0050569d98cc</ValueMappingID>
</bas:ValueMappingReadRequest>
</soapenv:Body>
</soapenv:Envelope>
Web service Response:-
<SOAP-ENV:Envelope xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns2:ValueMappingReadResponse xmlns:ns2="http://sap.com/xi/BASIS">
<ValueMapping>
<MasterLanguage>EN</MasterLanguage>
<AdministrativeData>
<ResponsibleUserAccountID>gdonna</ResponsibleUserAccountID>
<LastChangeUserAccountID>gdonna</LastChangeUserAccountID>
<LastChangeDateTime>2018-10-05T09:47:38.237-05:00</LastChangeDateTime>
<FolderPathID>/</FolderPathID>
</AdministrativeData>
<ValueMappingID>c44f541f-c8ac-11e8-86e5-0050569d98cc</ValueMappingID>
<GroupName>Mercedes</GroupName>
<Representation schemeAgencyID="LOC_BANK" schemeID="BANK">CHASE</Representation>
<Representation schemeAgencyID="LOC_SITE" schemeID="DIR">comm/as2/chase/receive/</Representation>
<Representation schemeAgencyID="LOC_COUNTRY" schemeID="CODE">US</Representation>
</ValueMapping>
<LogMessageCollection/>
</ns2:ValueMappingReadResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Try using a Groovy Script. I really like the features of the XMLSlurper, which lets me ignore the namespaces if/when they change.
Just add a new Groovy Script teststep, and put this into it. You just need to adjust the name of your Soap Request teststep, which should be placed just before this teststep.
/** The name should be modified to match the request/response you want to validate */
def holder = new com.eviware.soapui.support.GroovyUtils( context ).getXmlHolder("The Name Of Your Soap Request TestStep#Response")
def response = new XmlSlurper().parseText(holder.getXml())
for (def element : response.Body.ValueMappingReadResponse.ValueMapping.Representation)
{
log.info element
log.info element.#'schemeAgencyID'
}
I need two responses from soap web service where I should get the first response and after some time based on the element (ResponseCode in my case) in the first response, the second response should come. Below are the sample 2 responses I need form the soap web service
Response1:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://cp.abc.com/cpinterface/request">
<soapenv:Header/>
<soapenv:Body>
<req:ResponseMsg><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<Response>
<ResponseCode>0</ResponseCode>
<ResponseDesc>The service request is processed successfully.</ResponseDesc>
<ServiceStatus>0</ServiceStatus>
</Response>]]></req:ResponseMsg>
</soapenv:Body>
</soapenv:Envelope>
Response2:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<res:ResultMsg xmlns:res="http://cp.abc.com/cpinterface/result"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<Result>
<ResultType>0</ResultType>
<ResultCode>0</ResultCode>
<ResultDesc>Process service request successfully.</ResultDesc>
<ResultParameters>
<ResultParameter>
<Key>EndDate</Key>
<Value>20140103</Value>
</ResultParameter>
<ResultParameter>
<Key>EndTime</Key>
<Value>210156</Value>
</ResultParameter>
<ResultParameter>
<Key>Fee</Key>
<Value>0.89</Value>
</ResultParameter>
</ResultParameters>
</Result>]]></req:ResultMsg>
</soapenv:Body>
</soapenv:Envelope>
I don't think that's possible, HTTP(S) is one-on-one in the sense that there's one response to one request. There is potentially a loophole you may be able to exploit by using the HTTP status code 100 (continue). Status code 100 means; 'Sofar everything is fine, but more information is coming'. Your client should then continue to wait for the final SOAP response; which then has status code 200 (OK) or 500 (Error). Although in theory it is possible to use a different application protocol (e.g. JMS, SMTP or FTP) to transport SOAP messages, in practice it is usually HTTP(S).
Having said this, I think you shouldn't go down the statuscode 100 route but instead rethink your approach, stick with the 'one response for one request'. The above would be very hacky and tricky to implement.
I don't know if this is even possible, I've been looking around and haven't found anything even related to this... or maybe I'm just not using the right terms to find it.
The problem is this.. let's say I have this request:
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://request.dto.webservices.com/xsd">
<soap:Header/>
<soap:Body>
<impl:testServiceMethod>
<xsd1:booleanField1>?</xsd1:booleanField1>
</impl:testServiceMethod>
</soap:Body>
</soap:Envelope>
What's currently happening is that on the back-end side the booleanField1 (which is Boolean), is received as false instead of null. To get the null I have to remove the field from the request.
Is there a way to set anywhere on the code that behavior?
I am looking for solution how to remove <soapenv:Header> part from SOAP request using XML-based routing (Apache Camel Blueprint XML).
So this:
<soapenv:Envelope xmlns:net="..." xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
...
</soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
shall become just this:
<soapenv:Envelope xmlns:net="..." xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
I think I found java-based solution, also xslt-based solution, but I dont find them quite suitable for my project, and I still hope there is some simple way how to do it directly in XML route without creating java processing class or adding XSLT template.
I was trying <removeHeaders pattern="_something_"/> but either I cant figure out the correct "something", or this command only applies to headers above payload section...
In Blueprint you can get the body of the XML by using XPATH. Something like this:
<setProperty propertyName="MessageBody">
<xpath>//*[local-name()='Body']</xpath>
</setProperty>
Then you could reconstruct your message with the envelop tag.
<setBody>
<simple><![CDATA[<Envelope>${property.MessageBody}</Envelope>]]></simple>
</setBody>
This will only work if your Envelope tag is a constant.
The easiest way I would thing is to parse the SOAP message and then remove the header. You can do that with SAAJ.
How to remove empty header from SOAP message?
.removeHeaders() is for removing Camel exchange headers which is something completely different.
It depends on what dataformat you are using for the CXF endpoint, Is this SOAP request coming from someother service ?
Why are you not happy with XSLT ?
Regardless, You can remove if you use payload DATAFORMAT.
So I find perfect and very simple solution to my issue:
The contents of <soapenv:Header> (along with contents of <soapenv:Body>) were stored in CxfPayload object , which is part of org.apache.camel.Exchange
After I learned this, I was just one Groovy command, that can be easily included in routes.xml, away from solution:
<groovy>
exchange.getIn().getBody(org.apache.camel.impl.DefaultMessage.class).getBody(org.apache.camel.component.cxf.CxfPayload.class).getHeaders().clear();
</groovy>
I need to send a SOAP Message with the following format (cut down from example I was given): -
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ret="http://www.another.com/ret"
xmlns:ser="http://www.another.com/ret/retTransaction/service"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ser:store>
<ret:retTransaction>
<ret:retailTransaction xsi:type="ret:NormalTransaction"> <ret:applicationId>POS</ret:applicationId>
</ret:retailTransaction>
</ret:retTransaction>
</ser:store>
</soapenv:Body>
</soapenv:Envelope>
The operation in question is "store". That operation has an "object" parameter in the proxy following Add Service Reference.
How do I ensure that a message with the correct format is sent? Particularly the multiple namespaces in the SOAP Envelope?
Thanks