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()
Related
I'm trying to construct a simple header element (i.e. contextID) with org.apache.cxf.headers.Header
The XML representation should be like:
<soapenv:Header>
<contextID>someString</contextID>
</soapenv:Header>
I was trying like this in an interceptor:
String contextID = "someString";
List<Header> headers = message.getHeaders();
//this could be possibly wrong
Header contextIdHeader = new Header(new QName(CORE_NAMESPACE, "contextID"), contextID);
headers.add(contextIdHeader);
message.put(Header.HEADER_LIST, headers);
But I'm getting an exception:
java.lang.ClassCastException: java.lang.String cannot be cast to org.w3c.dom.Element
I suppose, the construction of the Header element is wrong.
What would be the correct way to do it?
Thank you!
Found the solution:
the Header element has to be created like this
Header contextIdHeader = new Header(new QName(CORE_NAMESPACE, "contextID"), contextID, new JAXBDataBinding(String.class));
Here is my code to run the POST request
// Instantiate HttpClient
HttpClient httpClient = new HttpClient();
// Configure HttpClient, for example:
httpClient.setFollowRedirects(false);
// Start HttpClient
httpClient.start();
ContentResponse response = httpClient.POST("url")
.agent("Mozilla/5.0")
.method(HttpMethod.POST)
.param("do","login")
.param("url","")
.param("vb_login_md5password", this.password)
.param("vb_login_md5password_utf", this.password)
.param("s", "")
.param("vb_login_username", this.username)
.param("vb_login_password", "")
.send();
for(HttpField h : response.getHeaders())
System.out.println(h.getName() + " = " + h.getValue());
Here is the output
Date = Mon, 14 Dec 2015 08:17:08 GMT
Content-Type = text/html
Transfer-Encoding = chunked
Connection = keep-alive
Set-Cookie = __cfduid=dbb11c371945319b1d5943aad06c1977e1450081028; expires=Tue, 13-Dec-16 08:17:08 GMT; path=/; domain=.sythe.org; HttpOnly
Server = cloudflare-nginx
CF-RAY = 2548787ba9dc21b6-EWR
I look at the ContentResponse text of the post request by doing
response.getContentAsString()
However for some reason I keep getting a 411 error which tells me my Content-Length is zero or not specified. Is there a way to set the content length header of the post?
Thanks!
EDIT : Doing this makes no difference in my post request
.header(HttpHeader.CONTENT_LENGTH, "0")
With .param("do","login") you specify a query param to be added. For the POST to actually contain a body I'd think you need to set content() on the request. Maybe a FormContentProvider will work for you?
I am pretty new in the WebServices interrogation using Java and I have the following problem.
I have a web service that provide to me a getConfigSettings() method that, by its response, say to me some informations including whether a user is enabled or not on a certain service (it say if the couple username and password is correct and if the user can log into the system).
In particular I have the following REQUEST of the getConfigSettings() method:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:getConfigSettings>
<!--Optional:-->
<tem:login>name.surname</tem:login>
<!--Optional:-->
<tem:password>rightPawssword</tem:password>
<!--Optional:-->
<tem:ipAddress>144.44.55.4</tem:ipAddress>
<!--Optional:-->
<tem:clientVersion>1</tem:clientVersion>
<!--Optional:-->
<tem:lastUpdateTime>2</tem:lastUpdateTime>
</tem:getConfigSettings>
</soapenv:Body>
</soapenv:Envelope>
And this is the webservice RESPONSE in case the couple username and password is correct and the user can log into the system:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<getConfigSettingsResponse xmlns="http://tempuri.org/">
<getConfigSettingsResult>
<![CDATA[
<root>
<status>
<id>0</id>
<message></message>
</status>
<drivers>
<drive id="tokenId 11">
<shared-secret>Shared 11</shared-secret>
<encoding>false</encoding>
<compression />
</drive>
<drive id="tokenId 2 ">
<shared-secret>Shared 2 </shared-secret>
<encoding>false</encoding>
<compression>false</compression>
</drive>
</drivers>
</root>
]]>
</getConfigSettingsResult>
</getConfigSettingsResponse>
</s:Body>
</s:Envelope>
In this response the important section is:
<status>
<id>0</id>
<message></message>
</status>
because <id>0</id> means that the user can log into the system
On the contrary if the couple username and password is incorrect I will obtain the following RESPONSE:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<getConfigSettingsResponse xmlns="http://tempuri.org/">
<getConfigSettingsResult><![CDATA[<root>
<status>
<id>-1</id>
<message>Login or password incorrect</message>
</status>
</root>]]></getConfigSettingsResult>
</getConfigSettingsResponse>
</s:Body>
</s:Envelope>
As you can see in this case I have that <id>-1</id> (that represent a situation of error) and in the message tag it specify the type of error occurred.
Ok, now I have to create a Java method that call this getConfigSettings() method passing to it the requested 5 parameters: login, password, ipAddress, clientVersion and lastUpdateTime (also if at this stage the only important parameters are login and password, the others can be whatever...)
And now I have no idea about how do it.
In my project there is another method that call another request report of the same web services that is:
public String getVersion() {
java.net.URL url = null;
java.net.URLConnection conn = null;
java.io.BufferedReader rd = null;
String soapResponse = "";
String risultato = "";
// SOAP ENVELOP for the request:
String soapRequest;
soapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" + "<soapenv:Header/>" + "<soapenv:Body> " + "<tem:getVersion/>" + "</soapenv:Body>" + "</soapenv:Envelope>";
try {
// Try to open a connection
url = new java.net.URL(_webServiceUrl);
conn = url.openConnection();
// Set the necessary header fields
conn.setRequestProperty("SOAPAction", "http://tempuri.org/IMyService/getVersion");
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setDoOutput(true);
// Send the request:
java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(conn.getOutputStream());
wr.write(soapRequest);
wr.flush();
// Read the response
rd = new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream()));
// Put the entire response into the soapResponse variable:
String line;
while ((line = rd.readLine()) != null) {
//System.out.println(line);
soapResponse = soapResponse + line + System.getProperty("line.separator");
}
rd.close();
// PERFORM SOME ELABORATION ON THE RESPONSE
..........................................
..........................................
..........................................
..........................................
return risultato;
}
Looking at this working method it seems to me that do something like that:
It create a String object that contain the SOAP Envelop for my request.
Try to connect to my WebService.
Then Set the necessary header fields (and this is not clear for me, what exactly mean? and what is tempuri?), what exactly do the following lines:
conn.setRequestProperty("SOAPAction", "http://tempuri.org/IMyService/getVersion");
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setDoOutput(true);
Send my prepared request to the WebService
Obtain the response and put it into my String soapResponse variable
This is what I want to obtain creating the other authentication() method, I have to create the SOAP Envelop using the previous parameters, send it to the webservice and obtain the SOAP response.
I think that my main problem is how to create the right String soapRequest object that use the parameter to do that.
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'm trying to send-retrive message from server by SOAP...
but
soapConnection.call( soapMessage, endpoint )
returns:
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to parse content type: null
Hereis my code:
String url = "https://pubcommission.api.cj.com/wsdl/version2/publisherCommissionServiceV2.wsdl";
String method = "findPublisherCommissionDetails";
SOAPConnection soapConnection = SOAPConnectionFactory.newInstance().createConnection();
SOAPFactory soapFactory = SOAPFactory.newInstance();
MessageFactory messageFactory = MessageFactory.newInstance();
// Create a message from the message factory.
SOAPMessage soapMessage = messageFactory.createMessage();
// creat a SOAP part have populate the envelope
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.setEncodingStyle( SOAPConstants.URI_NS_SOAP_ENCODING );
// remove all header information from envelope
envelope.getHeader().detachNode();
// create a SOAP body
SOAPBody body = envelope.getBody();
Name babelFishRequestName = envelope.createName( method, "ns1", "http://api.cj.com" );
SOAPBodyElement soapMethod = body.addBodyElement( babelFishRequestName );
// add elements translationmode and sourcedata to BabelFishRequest
soapMethod.addChildElement( soapFactory.createElement( "developerKey", "ns1", "http://api.cj.com" ).addTextNode( "nevermind" ) );
soapMethod.addChildElement( soapFactory.createElement( "originalActionIds", "ns1", "http://api.cj.com" ).addTextNode( "1234567" ) );
// set the saves into the structure
soapMessage.saveChanges();
// output the message
System.out.println( "\n============= start request msg ==========\n" );
soapMessage.writeTo( System.out );
System.out.println( "\n============= end request msg ==========\n" );
URLEndpoint endpoint = new URLEndpoint(url);
System.out.println( "\nSending message to URL: " + endpoint.getURL() );
// now make that call over the SOAP connection
SOAPMessage reply = soapConnection.call( soapMessage, endpoint );
I tried utility 'Membrane' to check result and got the following result (RAW):
HTTP/1.0 500 Internal Server Error
Server: Resin/3.1.8
Content-Type: text/xml; charset=UTF-8
Date: Wed, 08 Feb 2012 10:45:47 GMT
X-Cache: MISS from proxy.myserver.com
X-Cache-Lookup: MISS from proxy.myserver.com:3128
Via: 1.0 proxy.myserver.com (squid/3.1.18)
Connection: close
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Action id specified does not match your account: 1234567</faultstring></soap:Fault></soap:Body></soap:Envelope>
Don't know about that error. If using JAX-WS API is an option for you, this is the way to go:
Use wsimport tool to generate client objects:
wsimport.bat -keep -d "\ProjectDir\src" https://pubcommission.api.cj.com/wsdl/version2/publisherCommissionServiceV2.wsdl
This will generate everything you need to call the web service:
com.cj.api
com.cj.domain.transaction
com.cj.service.transaction
In the api package you find the service and port objects, the latter allows you to access the web service methods:
PublisherCommissionServiceV2 service = new PublisherCommissionServiceV2();
PublisherCommissionServiceV2PortType port = service.getPublisherCommissionServiceV2HttpPort();
port.findPublisherCommissionDetails("key", "id");
This will give you a nice not authenticated: key message from the web service.