I have used javax.xml.soap library to invoke soap request and response. I have wsdl endpoint url which works fine in SOAP-UI. I need to validate the same using java, and I created a soap request which looks different evnelop than the actual one as below
JAVA REQUEST PAYLOAD:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webservicex.com/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<web:GetCitiesByCountry>
<web:CountryName>US</web:CountryName>
</web:GetCitiesByCountry>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP REQUEST PAYLOAD:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header/>
<soapenv:Body>
<web:GetCitiesByCountry>
<!--Optional:-->
<web:CountryName>US</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
The JAVA request payload is not working as expected and it throws below error response.
<?xml version="1.0" encoding="utf-8"?><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><soap:Fault><faultcode>soap:Client</faultcode><faultstring>System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://www.webservicex.com/GetCitiesByCountry.
at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
I didn't find any difference between both request payload except the envelop, and I tried to modify the envelop by using
SOAPConstants.SOAP_1_1_PROTOCOL and 1_2 PROTOCOL but no luck.
The below code I tried so far:
private static SOAPMessage createSOAPRequest() throws Exception
{
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
//Tried to change the envelop which is not working
/*MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage soapMessage = messageFactory.createMessage();
soapMessage.getSOAPPart().setPrefix("soapenv");
soapMessage.getSOAPPart().removeMimeHeader("SOAP-ENV");
soapMessage.getSOAPHeader().setPrefix("soapenv");
soapMessage.getSOAPBody().setPrefix("soapenv");
messageFactory.createMessage();*/
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://www.webservicex.com/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("web", serverURI);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement(
"GetCitiesByCountry", "web");
SOAPElement soapBodyElem1 soapBodyElem.addChildElement("CountryName",
"web");
soapBodyElem1.addTextNode("US");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "GetCitiesByCountry");
System.out.println(soapMessage.getSOAPBody());
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
I copied the request payload and change the envelop from SOAP-ENV to sopaenv and invoked in SOAPUI which is return an appropriate response. So can somebody tell me how can I change the envelop tag by using java library.
can you try with
String serverURI = "http://www.webserviceX.NET";
instead of
String serverURI = "http://www.webservicex.com/";
Related
I'm very new to soap and i found an example of how to do a request here: Working Soap client example
Using a chrome plugin i've managed to find a soap query string that works which is:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<GetMyProjectCharges xmlns="http://company.IWWeb.Data.Service.ProjectCharges">
<Employee>26270</Employee>
<FiscalYear>2015</FiscalYear>
<ApiKey>APIKEY</ApiKey>
<AppName>APPNAME</AppName>
</GetMyProjectCharges>
</Body>
</Envelope>
So trying the code posted from the stack post I wrote:
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://schemas.xmlsoap.org/soap/envelope/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="http://ws.cdyne.com/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<example:VerifyEmail>
<example:email>mutantninja#gmail.com</example:email>
<example:LicenseKey>123</example:LicenseKey>
</example:VerifyEmail>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = //soapBody.addChildElement("GetMyProjectCharges");
soapBody.addChildElement("GetMyProjectCharges", "", "http://company.IWWeb.Data.Service.ProjectCharges");
SOAPElement soapBodyEmployee = soapBodyElem.addChildElement("Employee").addTextNode("26270");
SOAPElement soapBodyFiscalYear = soapBodyElem.addChildElement("FiscalYear").addTextNode("2015");
SOAPElement soapBodyAPIKey = soapBodyElem.addChildElement("ApiKey").addTextNode("APIKEY");
SOAPElement soapBodyAppName = soapBodyElem.addChildElement("AppName").addTextNode("APPNAME");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "GetMyProjectCharges");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
However I'm ending up with the following soap request code:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<GetMyProjectCharges xmlns="http://company.IWWeb.Data.Service.ProjectCharges">
<Employee>26270</Employee>
<FiscalYear>2015</FiscalYear>
<ApiKey>APIKEY</ApiKey>
<AppName>APPNAME</AppName>
</GetMyProjectCharges>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Which the server doesn't seem to happy about. Is there an easy way to modify what i'm doing to get a query string closer to what i want?
I am not familiar with SOAP requests so I have been reading up on it. The examples and tutorials I've looked at construct the request in an xml format in the SOAP envelope.
example:
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://ws.cdyne.com/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("example", serverURI);
/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="http://ws.cdyne.com/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<example:VerifyEmail>
<example:email>mutantninja#gmail.com</example:email>
<example:LicenseKey>123</example:LicenseKey>
</example:VerifyEmail>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("VerifyEmail", "example");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("email", "example");
soapBodyElem1.addTextNode("mutantninja#gmail.com");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("LicenseKey", "example");
soapBodyElem2.addTextNode("123");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "VerifyEmail");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
but the example request that was given to me by the organization with the server is a single line with the request in the URL:
http://sdmdataaccess.nrcs.usda.gov/Spatial/SDMNAD83Geographic.wfs?Service=WFS&Version=1.0.0&Request=GetFeature&OutputFormat=GML3&TypeName=MapunitPoly&FILTER=<Filter><Intersect><PropertyName>Geometry</PropertyName><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-95.1852448111,43.0186163988 -95.1853350008,43.0183961223 -95.1854898978,43.0183055981 -95.1858276893,43.0182603358 -95.1861146851,43.0183087828 -95.1862558373,43.0184050072 -95.186496397,43.0188380162 -95.1867287441,43.018969948 -95.1871860608,43.0190950058 -95.1872413814,43.0192924831 -95.1869109659,43.0195048805 -95.1863026073,43.019660449 -95.1860721056,43.0196581015 -95.185922908,43.0195072276 -95.1857936581,43.0191228335 -95.1853686954,43.0188252761 -95.1852448111,43.0186163988 -95.1852448111,43.0186163988</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></Intersect></Filter>
Here it is again but wrapped and indented for easier reading:
http://sdmdataaccess.nrcs.usda.gov/Spatial/SDMNAD83Geographic.wfs?
Service=WFS&
Version=1.0.0&
Request=GetFeature&
OutputFormat=GML3&
TypeName=MapunitPoly&
FILTER=<Filter>
<Intersect>
<PropertyName>Geometry</PropertyName>
<gml:Polygon>
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates>
-95.1852448111,43.0186163988
-95.1853350008,43.0183961223
-95.1854898978,43.0183055981
-95.1858276893,43.0182603358
-95.1861146851,43.0183087828
-95.1862558373,43.0184050072
-95.186496397,43.0188380162
-95.1867287441,43.018969948
-95.1871860608,43.0190950058
-95.1872413814,43.0192924831
-95.1869109659,43.0195048805
-95.1863026073,43.019660449
-95.1860721056,43.0196581015
-95.185922908,43.0195072276
-95.1857936581,43.0191228335
-95.1853686954,43.0188252761
-95.1852448111,43.0186163988
-95.1852448111,43.0186163988
</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</Intersect>
</Filter>
I'm not sure how to either modify this to handle the single line request or to modify the request to fit into this system. Any information would be helpful.
That's not SOAP. That's a simple GET request, in which one parameter is an XML document. As such, you can simply issue a GET request using Apache Http Components or similar.
Note that if you take the above URL and request it via your browser (a GET) you'll get an XML response back (which you'll need to parse appropriately)
I try to invoke a webservice in Java. Mainly I followed this link and also I solved several problems with google and other questions of stackoverflow. However, I get an error that I can not solve:
Exception in thread "main" javax.xml.ws.WebServiceException: javax.xml.stream.XMLStreamException: Non-default namespace can not map to empty URI (as per Namespace 1.0 # 2) in XML 1.0 documents
I think that the problem is in the xml that I created but I see well.
SOAPUI request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://url/acceso">
<soapenv:Header/>
<soapenv:Body>
<acc:petitionSession>
<acc:codUser/>
<acc:pass>?</acc:pass>
<acc:codOp>?</acc:codOp>
</acc:petitionSession>
</soapenv:Body>
</soapenv:Envelope>
Request I generated:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://url/acceso">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<acc:petitionSession>
<acc:codUser/>
<acc:pass>user1</acc:pass>
<acc:codOp>Temp1</acc:codOp>
</acc:petitionSession>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Code:
Dispatch dispatcher = getDispatcher(wsdlLocation, namespace, serviceName, portName);
dispatcher.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
dispatcher.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, soapActionUri);
...
...
public static SOAPMessage construirMensaje() throws SOAPException, IOException{
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage soapMsg = factory.createMessage();
SOAPPart part = soapMsg.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("acc", "http://url/acceso");
SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();
SOAPBodyElement element = body.addBodyElement(envelope.createName("petitionSession",
"acc", null));
element.addChildElement(body.addBodyElement(envelope.createName("codUser",
"acc", null)));
SOAPBodyElement pass = body.addBodyElement(envelope.createName("pass",
"acc", null));
pass.addTextNode("user1");
element.addChildElement(pass);
SOAPBodyElement codOp = body.addBodyElement(envelope.createName("codOp",
"acc", null));
codOp.addTextNode("Temp1");
element.addChildElement(codOp);
soapMsg.writeTo(System.out);
FileOutputStream fOut = new FileOutputStream("SoapMessage.xml");
soapMsg.writeTo(fOut);
System.out.println();
return soapMsg;
}
Any idea?
Regards.
I find the problem that was in the header that it wasn`t built well. It needed to add:
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "name");
I'm trying to call a SOAP webservice using SAAJ for this WSDL. I submitted the request for this WSDL here http://www.webservicex.net/ws/WSDetails.aspx?WSID=64and it generated the following SOAP requests..
<?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>
<GetGeoIP xmlns="http://www.webservicex.net/">
<IPAddress>string</IPAddress>
</GetGeoIP>
</soap:Body>
</soap:Envelope>
Using SAAJ I generated the same SOAP requests and submitted it but get this error - Server did not recognize the value of HTTP Header SOAPAction: .
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header/>
<SOAP-ENV:Body>
<GetGeoIP xmlns="http://www.webservicex.net/">
<IPAddress>SUNW</IPAddress>
</GetGeoIP>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Java Code:
package newpackage;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
public class SOAPClientSAAJ {
public static void main(String args[]) throws Exception {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "http://www.webservicex.net/geoipservice.asmx";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// print SOAP Response
System.out.print("Response SOAP Message:");
soapResponse.writeTo(System.out);
soapConnection.close();
}
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://www.w3.org/2001/XMLSchema";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("xsd", serverURI);
SOAPBody body = soapMessage.getSOAPBody();
QName bodyName = new QName("http://www.webservicex.net/", "GetGeoIP" );
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
QName name = new QName("IPAddress");
SOAPElement symbol = bodyElement.addChildElement(name);
symbol.addTextNode("SUNW");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
}
Add
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "http://www.webservicex.net/" + "GetGeoIP");
If you are using Marshelling and Unmarsheling, Just implement WebseviceMessageCallback interface like:
public class SOAPConnector extends WebServiceGatewaySupport
{
public Object callWebService( String url, Object request )
{
return getWebServiceTemplate().marshalSendAndReceive( url, request,
webServiceMessage -> {
(( SoapMessage )webServiceMessage).setSoapAction(
"https://www.w3schools.com/xml/CelsiusToFahrenheit" );
} );
}
}
Otherwise proceed with: https://stackoverflow.com/a/26253141/6097074
I have to call a Webservice with SOAP. I have made a client in Java that produces the following SOAPMessage:
<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:abc="http://company.com/SAMPLE/ABC">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<abc:genXX>
<ServiceRequestID>111</ServiceRequestID>
<Code>328630962</Code>
</abc:genXX>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
That call produces Error during parsing of SOAP when I call it inside my application:
<SOAP:Header>
</SOAP:Header>
<SOAP:Body>
<SOAP:Fault xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>SOAP:Client</faultcode>
<faultstring>Error during parsing of SOAP header</faultstring>
<faultactor>http://sap.com/xi/XI/Message/30</faultactor>
<detail>
<SAP:Error SOAP:mustUnderstand="1"
xmlns:SAP="http://sap.com/xi/XI/Message/30">
<SAP:Category>XIProtocol</SAP:Category>
<SAP:Code area="PARSER" />
<SAP:P1 />
<SAP:P2 />
<SAP:P3 />
<SAP:P4 />
<SAP:AdditionalText />
<SAP:Stack>System error in parser
</SAP:Stack>
</SAP:Error>
</detail>
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>
But when I call it with the same computer with SOAP UI the webservice responds well. The client in my application is made this way:
public void callWebservice(String serviceRequestID, String code) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory =
SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
URLEndpoint url = new URLEndpoint ("http://company.com:50000/");
SOAPMessage soapResponse = soapConnection.call(
createSOAPRequest(serviceRequestID, code), url);
{...}
soapConnection.close();
} catch (Exception e) {
//
}
private SOAPMessage createSOAPRequest(String serviceRequestID,
String code) throws SOAPException{
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://company.com/SAMPLE/ABC";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("abc", serverURI);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("genXXX", "abc");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("ServiceRequestID");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("Code");
soapBodyElem1.addTextNode(serviceRequestID);
soapBodyElem2.addTextNode(code);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI );
String loginPassword = "USER:PASSWORD";
headers.addHeader("Authorization", "Basic " + new
String(Base64.encodeBase64(loginPassword.getBytes())));
soapMessage.saveChanges();
return soapMessage;
}
}
I have checked header and authentication and it is right. If I change the user or password the Webservice respondos with a 401 Unauthorized so I think the header is sent as expected.
Do you have any clue on what's causing the error inside my application?
You are calling a web service in SAP PI (SAP Process Integration). I work as a PI developer and it is possible to use a SAP proprietary protocol over SOAP called XI protocal that is useful in SAP-SAP scenarios. If this service should be accessed by a non SAP system it should probably be changed to regular SOAP 1.1 protocol. Talk to the PI team.
A couple of years late to the party, but because I ran into pretty much the same issue today, here's the solution:
In order to communicate via SOAP 1.1 protocol as Richard L suggested, change your "SOAPAction" header to "http://sap.com/xi/WebService/soap1.1"
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
That did the trick for me.