Soap Request using java - Request call format issue - java

I'm trying to make a SOAP call with this Java code:
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("UserAuthentication", serverURI);
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("UserAuthentication", "UserAuthentication");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("user_name", "UserAuthentication");
soapBodyElem1.addTextNode("pqr#xyz.com");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("password", "UserAuthentication");
soapBodyElem2.addTextNode("123");
soapMessage.saveChanges();
The required format of SOAP call (I'm trying to generate) is:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<UserAuthentication xmlns="http://tempuri.org/">
<user_name>string</user_name>
<password>string</password>
</UserAuthentication>
</soap:Body>
</soap:Envelope>
But the actual call generated by my code doesn't match the required format and is rejected at the receiving end, and I'm trying to figure out why and how to fix it:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:UserAuthentication="http://XXX.XXX.XXX.XXX:XXXX/Logininfo.asmx?op=UserAuthentication">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<UserAuthentication:UserAuthentication>
<UserAuthentication:user_name>pqr#xyz.com</UserAuthentication:user_name>
<UserAuthentication:password>123</UserAuthentication:password>
</UserAuthentication:UserAuthentication>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

What's the error message from the receiving end?
In any case, the namespaces for the UserAuthentication elements differ.
Expected: http://tempuri.org/
Actual: http://XXX.XXX.XXX.XXX:XXXX/Logininfo.asmx?op=UserAuthentication

envelope.addNamespaceDeclaration("UserAuthentication", serverURI);
Why are you adding that namespace when given you desired request it is not needed?
Try removing that line. Then this one:
SOAPElement soapBodyElem = soapBody.addChildElement("UserAuthentication", "UserAuthentication");
Make it:
QName bodyName = new QName("http://tempuri.org/",
"UserAuthentication", "m");
SOAPElement soapBodyElem = soapBody.addChildElement(bodyName);

Related

How to apply a prefix to all Child elements in SOAP message

While structuring SOAP message having an issue with adding prefix to the subelement of ext:msg_LocationDetails element using QName and javax.xml.soap.Name
I'm using javax.xml.soap.SOAPFactory
When i try to use QName mag = new QName("","Messages","ext");
(new QName(namespaceURI, localPart, prefix))
Exception in thread "main" org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.setName(ElementNSImpl.java:149)
at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.<init>(ElementNSImpl.java:80)
at com.su
It gives the above exception.
SOAPBody soapBody = soapEnvelope.getBody();
soapBody = soapMessage.getSOAPBody();
soapBody.setPrefix("soapenv");
// To add some element
SOAPFactory soapFactory = SOAPFactory.newInstance();
Name bodyName = soapFactory.createName("msg_LocationDetails");
SOAPBodyElement locationDetails = soapBody.addBodyElement(bodyName);
locationDetails.setPrefix("ext");
QName mag = new QName("","Messages","ext");
SOAPElement messages = locationDetails.addChildElement(mag);
//SOAPElement messages = locationDetails.addChildElement("Messages");
//messages.addNamespaceDeclaration("fir", "");
//SOAPElement message = messages.addChildElement("message");
Below is the SOAP message
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ext="http://extdomain.com/">
<soapenv:Header/>
<soapenv:Body>
<ext:msg_LocationDetails>
<ext:Messages>
<ext:Message>
<ext:Location>GSA</ext:Location>
<ext:LocCode>Unit</ext:LocCode>
<ext:LocID>00004</ext:LocID>
<ext:SystemID>TSKSLSLSJJ</ext:SystemID>
<ext:Status>
<ext:ID>4</ext:ID>
<ext:Name>PENDING</ext:Name>
</ext:Status>
</ext:Message>
</ext:Messages>
</ext:msg_LocationDetails>
</soapenv:Header/>
</soapenv:Body>

How do you set Type attribute to a child element in a SOAP request?

I need to add Type to the password child element.
Current SOAP request -
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>user123</wsse:Username>
<wsse:Password>xxxxx</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
Code generating this -
String prefix = "wsse";
SOAPElement security = header.addChildElement("Security", prefix);
SOAPElement token = security.addChildElement("UsernameToken", prefix);
token.addChildElement("Username", prefix).addTextNode("user123");
token.addChildElement("Password", prefix).addTextNode("xxxxx");
I need to generate a SOAP request like -
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>user123</wsse:Username>
<wsse:Password Type="http://abc.def-ghi.org/wss/2016/09/xyz-wss-username-token-profile-1.0#PasswordText">xxxxx</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
String prefix = "wsse";
SOAPElement security = header.addChildElement("Security", prefix);
SOAPElement token = security.addChildElement("UsernameToken", prefix);
token.addChildElement("Username", prefix).addTextNode("user123");
SOAPElement passwordElement = token.addChildElement("Password",prefix).addTextNode('xxxxx');
passwordElement.setAttribute("Type", "http://abc.def-ghi.org/wss/2016/09/xyz-wss-username-token-profile-1.0#PasswordText");

Add namespace prefix Axis2

This is envelope which i wanna to send to service:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<sear:searchUrls>
<sear:in0>Safeway, 200 S. 3rd St, Renton, WA</sear:in0>
</sear:searchUrls>
</soapenv:Body>
</soapenv:Envelope>
And this is code to construct it:
SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
SOAPEnvelope envelope = fac.getDefaultEnvelope();
OMNamespace omNs = fac.createOMNamespace("http://schemas.xmlsoap.org/soap/envelope/", "soapenv");
OMNamespace ns1 = fac.createOMNamespace("http://search", "sear");
envelope.setNamespace(omNs);
OMNamespace ns = fac.createOMNamespace("", "")
OMElement method = fac.createOMElement("sear:searchUrls", ns);
OMElement value = fac.createOMElement("sear:in0", ns);
value.setText("Safeway, 200 S. 3rd St, Renton, WA");
method.addChild(value);
envelope.getBody().addChild(method);
But my namespace prefix "sear" is not defined.
How can I set it in code to get
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sear="http://search">
in XML?
envelope.addNamespaceDeclaration("sear", "http://search");
OMNamespace xsi = soapFactory.createOMNamespace(
Constants.URI_DEFAULT_SCHEMA_XSI,
Constants.NS_PREFIX_SCHEMA_XSI);
envelope.declareNamespace(xsi);
Do you have the WSDL and know the end point url ?
You can generate the client side code using the wsdl2java convertor.
More information at http://axis.apache.org/axis2/java/core/docs/userguide-creatingclients.html#choosingclient

Soap response iterat in java

I am using java soap request and response in my code. I am getting the request and response properly.
But I am not able to iterate the response
Please see my response and code used to iterate below. Please help me to resolve this issue.
Response
<?xml version="1.0" encoding="utf-16"?>
<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>
<GetUserResponse xmlns="http://XXXX.com/XXXXXXXX.XXXXXXX.WS">
<GetUserResult>
user
<PersonID>111113</PersonID>
<Username>0987654321</Username>
<Password />
<FwyMember>Y</FwyMember>
<WebMember>Y</WebMember>
<FirstName>Mohamed</FirstName>
<Tier>firstclass</Tier>
<CountryOfResidence>IN</CountryOfResidence>
<PreferencesChanged>false</PreferencesChanged>
<FamilyRelationship />
<Title>Mr</Title>
<MiddleName />
........ continue like this
Java code
SOAPBody responseBody = response.getSOAPBody();
QName bodyName1 = new QName("http://XXXX.com/XXXXXXXX.XXXXXXX.WS","GetUserResponse");
java.util.Iterator iterator = responseBody.getChildElements(bodyName1);
while (iterator.hasNext()) {
SOAPBodyElement responseElement = (SOAPBodyElement)iterator.next();
String val = responseElement.getValue();
System.out.println("The values are "+val);
}
There is only one GetUserResponse element below Body. getChildElements only gets child elements, as opposed to descendant elements. You must first reach GetUserResponse and then iterate over its children.

Java SOAP - Need help on Body and ChildElement manipulation

I'm trying to write some code in java to learn more about coding with WSDL and SOAP.
For example given :'<'to:checkAccount xmlns:to="http://foo">
'<'to:id> test '<'/to:id>
'<'to:password> test '<'/to:password>
'<'to:checkAccount >"
'<'element name="checkAccountResponse">
'<'complexType>
'<'sequence>
'<'element name="checkAccountReturn" type="impl:account"/>
'<'/sequence>
'<'/complexType>
'<'/element>
'<'complexType name="account">
'<'sequence>
'<'element name="active" type="xsd:boolean"/>
'<'element name="name" type="xsd:string"/>
'<'/sequence>
'<'/complexType>
my code looks like this at the moment:
//create the message
String endpoint = "http://foo/someAPI";
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader header = message.getSOAPHeader();
//adding to the body
SOAPBody body = message.getSOAPBody();
SOAPFactory soapFactory = SOAPFactory.newInstance();
Name bodyName = soapFactory.createName("checkAccount","to","http://foo");
SOAPElement bodyElement = body.addBodyElement(bodyName);
//add the ID child elements
soapFactory = SOAPFactory.newInstance();
Name childName = soapFactory.createName("id","to","http://foo");
SOAPElement symbol = bodyElement.addChildElement(childName);
symbol.addTextNode("test");
//add password child element
soapFactory = SOAPFactory.newInstance();
childName = soapFactory.createName("password","to","http://foo");
symbol = bodyElement.addChildElement(childName);
symbol.addTextNode("test");
//call and get the response
SOAPMessage response = sc.call(message,endpoint);
//print the response
SOAPBody responseBody = response.getSOAPBody();
java.util.Iterator iterator = responseBody.getChildElements(bodyName);
.
.
.
//the response is blank so trying to iterate through it gives the exception
I run this and i get nothing in return , just blank. I know my endpoint is correct , as well as the checkAccount ,id and password since I've tested it in xmlSpy and it returns account status.
It has to be the way I'm trying to get the response. Can someone please give me a hint?
This is how I would do it.
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPBody body = message.getSOAPBody();
SOAPElement checkAccEl = body
.addChildElement("checkAccount", "to", "http://foo");
SOAPElement idEl = checkAccEl
.addChildElement("id", "to", "http://foo");
idEl.addTextNode("test");
SOAPElement passwordEl = checkAccEl
.addChildElement("password", "to", "http://foo");
passwordEl.addTextNode("test");
// print out the SOAP Message. How easy is this?!
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out);
System.out.println(out.toString());
The first time you use the namespace 'to=http://foo' it is automatically declared on the element - checkAccount in this case. When you use the same namespace again, the XML won't need to declare it again, but will use the prefix.
The output looks like:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<to:checkAccount xmlns:to="http://foo">
<to:id>test</to:id>
<to:password>test</to:password>
</to:checkAccount>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Which is what you want I think

Categories