So I have this SOAP Message:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV=" http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<pid:pid xmlns:pid="pt:ulisboa:tecnico:sdis:store:ws">carla</pid:pid> </SOAP-ENV:Header> <S:Body><ns2:
loadResponse xmlns:ns2="urn:pt:ulisboa:tecnico:sdis:store:ws"/></S:Body>
</S:Envelope>
So you see pid="carla"
But when I get all the attributes:
Iterator iter = hd.extractAllHeaderElements();
while(iter.hasNext()){
System.out.println(iter.next());
}
All it prints is:
[pid:pid: null]
Any ideas why it isn't "carla"?
I'm doing all this processing in the handlers.
Related
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);
I have such a line:
SOAPMessage soapResponse = soapConnection.call(message, url);
and response looks:
HTTP/1.1 200 OK
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 24 Jul 2013 07:44:39 GMT
Server: Apache-Coyote/1.1
<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:Header>
<TransactionID soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="1" xmlns="http://somelink"></TransactionID>
</soapenv:Header>
<soapenv:Body>
<soap-env:Fault xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:faultcode>Server</soap-env:faultcode>
<soap-env:faultstring>Server Error</soap-env:faultstring>
<soap-env:Detail>
<soap-env:Status>
<soap-env:StatusCode>3000</soap-env:StatusCode>
<soap-env:StatusText>Server Error</soap-env:StatusText>
<soap-env:Details></soap-env:Details>
</soap-env:Status>
</soap-env:Detail>
</soap-env:Fault>
</soapenv:Body>
</soapenv:Envelope>
how can i get StatusCode (3000) in String from such a soap response?
i tried soapResponse.getSOAPBody().... but all i could get was :status
EDIT:
so i did:
Detail detail = soapResponse.getSOAPPart().getEnvelope().getBody().getFault().getDetail();
Iterator detailEntries = detail.getDetailEntries();
while (detailEntries.hasNext()) {
SOAPBodyElement bodyElement = (SOAPBodyElement) detailEntries.next();
Iterator val = bodyElement.getChildElements();
while (val.hasNext()) {
SOAPBodyElement bodyElement2 = (SOAPBodyElement) val.next();
String val2 = bodyElement2.getValue();
logger.debug("The Value is:" + val2);
}
but got class cast exception
}
Edit2: Solution:
soapResponse.getSOAPPart().getEnvelope().getBody().getFault().getDetail().getTextContent().trim().substring(0, 4));
Starting from the SOAPMessage, you need to call SOAPMessage#getSOAPPart() to obtain a SOAPPart.
By calling SOAPPart#getEnvelope() you can obtain the SOAPEnvelope.
Next you get the SOAPBody using SOAPEnvelope#getBody().
Now you can get the SOAPFault by calling SOAPBody#getFault().
Next, you call SOAPFault#getDetail() to obtain the Detail.
Using Detail#getDetailIterator() you can iterate over all of the DetailEntrys in the Detail object.
Since the DetailEntry interface extends the SOAPElement interface, you can get its content by calling getChildElements(); that way you can navigate to the StatusCode element inside the Status element and get its value.
soapResponse.getBody().getFault().getFaultCode()
http://docs.oracle.com/javaee/5/api/javax/xml/soap/SOAPFault.html#getFaultCode()
and iterate on :
soapResponse.getBody().getFault().getDetailEntries()
http://docs.oracle.com/javaee/5/api/javax/xml/soap/Detail.html#getDetailEntries()
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
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.
Why can I set a faulString, but can't I set a custom fault code in a SOAPFault? When I throw the exception, the text "Code X" does not appear in the SoapFaultException. Someone could tell me why? Thanks.
SOAPFault soapFault = SOAPFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL).createFault();
soapFault.setFaultString("String Y")
soapFault.setFaultCode("Code X");
throw new SOAPFaultException(soapFault);
It is possible to get the fault code in the soap response with the following example:
String faultString = "String Y";
String faultCodeValue = "Code X";
QName faultCode = new QName("nameSpaceURI", faultCodeValue);
SOAPFault soapFault = null;
try {
soapFault = SOAPFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL).createFault(faultString, faultCode);
throw new javax.xml.ws.soap.SOAPFaultException(soapFault);
} catch (SOAPException e1) {
//
}
I get the following soap fault back:
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope" xmlns="">
<faultcode xmlns:ns0="nameSpaceURI">ns0:Code X</faultcode>
<faultstring>String Y</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
From documentation:
Fault codes, which given information about the fault, are defined in
the SOAP 1.1 specification. This element is mandatory in SOAP 1.1.
Because the fault code is required to be a QName it is preferable to
use the setFaultCode(Name) form of this method.
faultCode - a String giving the fault code to be set. It must be of
the form "prefix:localName" where the prefix has been defined in a
namespace declaration.
Notice that the fault code your're setting has to be this format: prefix:localName. You're setting: Code X, that is why you do not see it. Use this method and all should be OK.