问题
I am trying to get response from web service using curl and c++. I have tried calling the web service from terminal. It works fine I can receive the response.
But I cannot able to reproduce the same through c++.
Request.xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:blz="http://thomas-bayer.com/blz/“>
<soapenv:Header/>
<soapenv:Body>
<blz:getBank>
<blz:blz>50070010</blz:blz>
</blz:getBank>
</soapenv:Body>
</soapenv:Envelope>
void dataFromWebService :: connectWithWebservice(){
struct curl_slist *header = NULL;
header = curl_slist_append (header, "Content-Type:text/xml");
header = curl_slist_append (header, "charset=UTF-8");
header = curl_slist_append (header, "SOAPAction:urn:getBank");
curl = curl_easy_init();
if(curl == NULL){
cout<<"CURL is NULL";
}
const char *myUrl = "http://www.thomas-bayer.com/axis2/services/BLZService";
//const char *myUrl = "http://11.22.33.231:9080/VehicleInfoQueryService.asm";
if(curl){
string Mydata;
char errbuf[CURL_ERROR_SIZE];
struct MemoryStruct chunk;
chunk.memory = (char*)malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
FILE * rfp = fopen("request.xml", "r");
curl_easy_setopt(curl, CURLOPT_URL, myUrl);
//curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, rfp);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
char *response = NULL;
/* passing the pointer to the response as the callback parameter */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
errbuf[0] = 0;
cout<< "The result from webservice "<<endl;
/* Perform the request, res will get the return code */
curlCode = curl_easy_perform(curl);
/* send all data to this function */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,(void *)&chunk);
cout <<"curl code-- "<<curlCode<<endl;
// always cleanup
if(curlCode != CURLE_OK | curlCode != 0) {
size_t len = strlen(errbuf);
fprintf(stderr, "\nlibcurl: (%d) ", curlCode);
if(len)
fprintf(stderr, "%s%s", errbuf,
((errbuf[len - 1] != '\n') ? "\n" : ""));
else
fprintf(stderr, "%s\n", curl_easy_strerror(curlCode));
} else {
/*
* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*/
printf("%lu bytes retrieved\n", (long)chunk.size);
cout<<"My Chunck -- "<<chunk.memory<<endl;
}
curl_easy_cleanup(curl);
}
}
output from code:
The result from webservice
* Trying 80.152.243.114...
* Connected to www.thomas-bayer.com (80.152.243.114) port 80 (#0)
> GET /axis2/services/BLZService HTTP/1.1
Host: www.thomas-bayer.com
Accept: */*
Content-Type:text/xml
SOAPAction:urn:getBank
< HTTP/1.1 500 Internal Server Error
< Server: Apache-Coyote/1.1
< Content-Type: application/xml;charset=UTF-8
< Date: Fri, 02 Dec 2016 10:56:36 GMT
< Connection: close
< Content-Length: 2388
<
* Closing connection 0
curl code-- 0
2388 bytes retrieved
My Chunck -- <?xml version="1.0" ?><Exception>org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /axis2/services/BLZService and the WSA Action = null
at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:86)
at org.apache.axis2.engine.Phase.invoke(Phase.java:308)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:212)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:132)
at org.apache.axis2.transport.http.util.RESTUtil.invokeAxisEngine(RESTUtil.java:125)
at org.apache.axis2.transport.http.util.RESTUtil.processURLRequest(RESTUtil.java:119)
at org.apache.axis2.transport.http.AxisServlet$RestRequestProcessor.processURLRequest(AxisServlet.java:799)
at org.apache.axis2.transport.http.AxisServlet.doGet(AxisServlet.java:242)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
</Exception>
Hello, World!
From terminal:
command:
curl --header "Content-Type: text/xml;charset=UTF-8" --header "SOAPAction:urn:getBank" --data @request.xml http://www.thomas-bayer.com/axis2/services/BLZService
Output:
<?xml version='1.0' encoding='UTF-8’?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/“>
<soapenv:Body>
<ns1:getBankResponse xmlns:ns1="http://thomas-bayer.com/blz/“>
<ns1:details>
<ns1:bezeichnung>
Deutsche Bank Filiale
</ns1:bezeichnung>
<ns1:bic>
DEUTDEFFXXX
</ns1:bic>
<ns1:ort>
Frankfurt am Main
</ns1:ort>
<ns1:plz>
60254
</ns1:plz>
</ns1:details>
</ns1:getBankResponse>
</soapenv:Body>
</soapenv:Envelope>
回答1:
it is little embarrassing to answer my own question.
I have to use Http Post with the request char* instead of file pointer of the request.
So the following works.
char* req= "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:blz=\"http://thomas-bayer.com/blz/\"> <soapenv:Header/> <soapenv:Body> <blz:getBank> <blz:blz>50070010</blz:blz> </blz:getBank> </soapenv:Body> </soapenv:Envelope>";
curl_easy_setopt(curl,CURLOPT_HTTPPOST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req);
This may be the reason SOAP only works with POST method even though it is transported by HTTP since "Standard SOAP services are using only HTTP POST because they require complex SOAP request (XML) which cannot be included in query string.”
but I don’t know how this example from curl works.
Thanks.
来源:https://stackoverflow.com/questions/40930863/cant-able-to-receive-response-from-web-service-using-curl-from-c