call SOAP webservice from external application

2,104 views
Skip to first unread message

giuseppe giorgio

unread,
Oct 3, 2013, 8:08:14 AM10/3/13
to google-a...@googlegroups.com
i need to write a full http request for invoke a soap webservice hosted on app engine, but i'm not able to send request. I'm programming an arduino borad, and there's no library for invoke webservice (so i need to built it).
what code should do it's to open an http connection with webservice, then send http request with xml for call service, but if i open connection by using webservice address, nothing works. The code show below it's clear also if you don't know arduino language:


char server[] = "arduino-data-server.appspot.com";

Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("POST arduino-data-server.appspot.com/dataserver HTTP/1.1");
    client.println("Host: www.google.com");
    client.println("Content-Length: nnn");
    client.println("Connection: close");
    client.println();
  }
}


how can i fix it?

Jim

unread,
Oct 3, 2013, 3:00:57 PM10/3/13
to google-a...@googlegroups.com
Is the app engine app yours?  If so perhaps you could expose your service as a RESTful service rather than SOAP since you don't have a SOAP client library on your arduino platform.  The REST service will be much simpler to consume with basic HTTP programming methods.

giuseppe giorgio

unread,
Oct 3, 2013, 3:11:28 PM10/3/13
to google-a...@googlegroups.com
Yes, it's mine, but i need to keep soap because i've already write other consumers client for soap services, and i can't change it all!
The only issue it's to know how http request for soap service is formed.
It's a peculiarity of soap to be independent from plattform, and it should work also on arduino by write full http request :)

Vinny P

unread,
Oct 3, 2013, 5:27:00 PM10/3/13
to google-a...@googlegroups.com
On Thu, Oct 3, 2013 at 7:08 AM, giuseppe giorgio <gio...@gmail.com> wrote:
i need to write a full http request for invoke a soap webservice hosted on app engine, but i'm not able to send request. I'm programming an arduino borad, and there's no library for invoke webservice (so i need to built it).
what code should do it's to open an http connection with webservice, then send http request with xml for call service, but if i open connection by using webservice address, nothing works.


Is the connection itself working? Try taking the code from http://arduino.cc/en/Tutorial/WiFiWebClientRepeating and checking to make sure you can pull a simple text file or HTML page from your application. 

If the client is working, then you should see logs in the Admin Console. Do those logs say anything?

 
-----------------
-Vinny P
Technology & Media Advisor
Chicago, IL

App Engine Code Samples: http://www.learntogoogleit.com

giuseppe giorgio

unread,
Oct 3, 2013, 5:33:21 PM10/3/13
to google-a...@googlegroups.com
Sure, the connection works. I've used sample code WiFiWebClient for sending http request to soap client (client like tutorial on google developer) but i'm not able to reach client. I've also paste a http request sniffed from wireshark, but nothing happen..

giuseppe giorgio

unread,
Oct 4, 2013, 1:22:11 PM10/4/13
to google-a...@googlegroups.com
UPDATES: i've run on localhost a java soap client example, and sniff again packet. Client request first of all wsdl file from server, send ok, then prepare the http+xml request.
On my arduino i don't need the wsdl file because i manually build http request. This is how i've implement http request on arduino:

char server[] = "http://arduino-data-server.appspot.com"; //server address
if(client.connect(server, 80)) {
    Serial.println("Connected to server, preparing request.");
    //prepare soap request
    
    client.println("POST /dataserver HTTP/1.1");
    client.println("Accept: text/xml, multipart/related");
    client.println("Content-Type: text/xml; charset=utf-8");
    client.println("SOAPAction: \"http://example.com/Functions/SendDataRequest\"");
    client.println("User-Agent: unknow");
    client.println("Content-Lenght: 208");
    client.println("Host: arduino-data-server.appspot.com");
    client.println("Connection: Keep-Alive");
    client.println();
    client.println("<?xml version=\"1.0\"");
    client.println("<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\"");
    client.println("<S:Body>");
    client.println("<ns2:sendData xmlsn:ns2=\"http://example.com\">");
    client.println("<arg0> 33 </arg0>");
    client.println("<arg1> 77% </arg1>");
    client.println("</ns2:sendData>");
    client.println("</S:Body>");
    client.println("</S:Envelope>");
  
    Serial.println("richiesta inviata");
}

but there's something strange. If i've write a wrong http request, on my server log i should see an error log, but no log of arduino request appear on my log. Also if i call only connect function i should see something on log, but nothing of this happen

Vinny P

unread,
Oct 4, 2013, 11:38:05 PM10/4/13
to google-a...@googlegroups.com
On Fri, Oct 4, 2013 at 12:22 PM, giuseppe giorgio <gio...@gmail.com> wrote:
If i've write a wrong http request, on my server log i should see an error log, but no log of arduino request appear on my log. Also if i call only connect function i should see something on log, but nothing of this happen



I'm not sure this is an App Engine problem then. There should be some sort of logs showing the incoming request - if there aren't any, App Engine may not be receiving the request in the first place, or be unable to interpret the request.

Is there any firewall or anything filtering the Arduino communications?

giuseppe giorgio

unread,
Oct 5, 2013, 3:37:32 AM10/5/13
to google-a...@googlegroups.com
I've paste in previous message the arduino code (maybe you don't receive email notification), take a look.
The log i check is the appengine backend log, relative to my webservice, and (i've already try) also if server receive bad request, log save it. No firewall block network comunication because if i use the same code for send http request for google search everithing works.
What i think is that code it's unable to connect to webservice for some dns problem. in fact also if i try to ping webservice address ( arduino-data-server.appspot.com ) the ip showed it's referred to anothe address ( appspot.l.google.com )

Vinny P

unread,
Oct 5, 2013, 11:16:40 PM10/5/13
to google-a...@googlegroups.com
On Sat, Oct 5, 2013 at 2:37 AM, giuseppe giorgio <gio...@gmail.com> wrote:
I've paste in previous message the arduino code take a look.


I did look at the code. I don't see anything particularly wrong with it, but I haven't tested it on an Arduino myself.


On Sat, Oct 5, 2013 at 2:37 AM, giuseppe giorgio <gio...@gmail.com> wrote:
What i think is that code it's unable to connect to webservice for some dns problem


Try using a HTTP client library and use SOAP over that. This library works, despite the fact that it hasn't been updated recently: https://github.com/amcewen/HttpClient
 

On Sat, Oct 5, 2013 at 2:37 AM, giuseppe giorgio <gio...@gmail.com> wrote:
in fact also if i try to ping webservice address ( arduino-data-server.appspot.com ) the ip showed it's referred to anothe address ( appspot.l.google.com )



That's normal, the same configuration exists for other appspot applications as well. 

giuseppe giorgio

unread,
Oct 9, 2013, 3:26:45 AM10/9/13
to google-a...@googlegroups.com
Ok, i've solved my problem. first of all i've build separate function for generate xml message. In this way i could calculate the exact length of http body. 
And a note for who will try to do something like me. When you need to assign value to Content length attribute, avodi to code like

client.println("Content-Length:"+body.length());


but do it in the correct way

client.print("Content-Length:");
client
.println(body.length());

So thank you for help me

Carlos Bologna

unread,
Dec 28, 2013, 4:39:19 PM12/28/13
to google-a...@googlegroups.com
Hi!

Can you show me your code? I made the same thing that you said, but it doesn't work for me yet. 

Thanks!

giuseppe giorgio

unread,
Jan 1, 2014, 10:47:02 AM1/1/14
to google-a...@googlegroups.com
the full code it's specific for my application, so you need to modify it for your purpose. If you have some doubt try to do some reversing: just create a SOAP web client (as showed on tutorial) and sniff related http packet for see the right structure that your request shuuld have.

void doPost(String temperature, String humidity) {
  String body = HttpRequestBody(temperature, humidity);
  Serial.println("Preparing connection to server");
  if(client.connect(server, 80)) {
    Serial.println("Connected to server, sending request.");
    //Send HTTP POST request
    client.println("POST /dataserver HTTP/1.1");
    client.println("Accept: text/xml, multipart/related");
    client.println("Content-Type: text/xml; charset=utf-8");
    client.println("SOAPAction: \"http://example.com/Functions/sendDataRequest\"");
    client.println("User-Agent: Arduino WiFiShield");
    client.print("Content-Length: ");
    client.println(body.length());
    client.println("Host: arduino-data-server.appspot.com");
    client.println("Connection: Close");
    client.println();
    client.println(body);
    client.println();
    client.stop();
    Serial.println("Request sent");

String HttpRequestBody(String temp, String hum) {
  String res = "";
  res += "<?xml version=\"1.0\"?>\n\r";
  res +="<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\">\n\r";
  res +="<S:Body>\n\r";
  res +="<ns2:sendData xmlns:ns2=\"http://example.com/\">\n\r";
  res +="<arg0>"+temp+"</arg0>\n\r";
  res +="<arg1>"+hum+"</arg1>\n\r";
  res +="</ns2:sendData>\n\r";
  res +="</S:Body>\n\r";
  res +="</S:Envelope>";
  
  return  res;
}


olivan aires

unread,
May 28, 2014, 8:39:36 AM5/28/14
to google-a...@googlegroups.com
oi, poderia me dar uma ajuda.
estou tentando fazer algo parecido com o que vc fez, mas não esta dando muito certo. a requisição não chega no meu webserver local que estou rodando com o jboss.

criei um dynamic web project com o nome JaxWsSample

esse é o código do meu webservice
package com.br.service.impl;

@WebService
public class PushNotificationServiceImpl implements PushNotificationServiceLocal {

   @Override
   @WebMethod
   public void sendPushNotification( @WebParam( name = "msg" )   String msg ) {
BasicConfigurator.configure();
try {
PushNotificationPayload notificacao = PushNotificationPayload.complex();
notificacao.addAlert( msg );
notificacao.addBadge( 1 );
notificacao.addSound( "default" );
notificacao.addCustomDictionary( "id", "1" );

System.out.println( notificacao.toString() );
List<PushedNotification> NOTIFICATIONS = Push.payload( notificacao, "ck.p12", "SENHA", false, "TOKEN" );

for ( PushedNotification NOTIFICATION : NOTIFICATIONS ) {
if ( NOTIFICATION.isSuccessful() ) {
System.out.println( "Notificação enviada com sucesso para: " + NOTIFICATION.getDevice().getToken() );

} else {
// String INVALIDTOKEN =
// NOTIFICATION.getDevice().getToken();

Exception THEPROBLEM = NOTIFICATION.getException();
THEPROBLEM.printStackTrace();

ResponsePacket THEERRORRESPONSE = NOTIFICATION.getResponse();
if ( THEERRORRESPONSE != null ) {
System.out.println( THEERRORRESPONSE.getMessage() );
}
}
}

} catch ( CommunicationException e ) {
e.printStackTrace();
} catch ( KeystoreException e ) {
e.printStackTrace();
} catch ( JSONException e ) {
e.printStackTrace();
}
}
   }

utilizando o SoapUI que simula um webclient, pude fazer os testes e funcionol corretamente, mas ao tentar fazer com o arduino nada aconteceu.

esse é o código que estou utilizando no arduino
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

char server[] = "192.168.0.28";    // meu ip

IPAddress ip(192,168,0,177); // ip para o arduino

EthernetClient client;

void setup() {
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Ethernet.begin(mac, ip);
  
  delay(1000);
  Serial.println("connecting...");

  doPost("Teste notificacao push");
  
}

void loop()
{
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    while(true);
  }
}

void doPost(String msg) {
  String body = HttpRequestBody(msg);

  Serial.println("Preparing connection to server");
  if(client.connect(server, 80)) {
    Serial.println("Connected to server, sending request.");
    //Send HTTP POST request
    client.println("POST /PushNotificationServiceImpl HTTP/1.1 HTTP/1.1");
    client.println("Accept-Encoding: gzip,deflate");
    client.println("Content-Type: text/xml; charset=UTF-8");
    client.println("SOAPAction: \"http://impl.service.br.com/PushNotificationServiceImpl/sendPushNotification\"");
    client.println("User-Agent: arduino-ethernet");
    client.print("Content-Length: ");
    client.println(body.length());
    client.println("Host: 192.168.0.28:8080");
    client.println("Connection: Keep-Alive");

    client.println();
    client.println(body);
    client.println();
    client.stop();
    Serial.println("Request sent");
    Serial.println(body);
    Serial.println(body.length());
  }
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

String HttpRequestBody(String msg) {
  Serial.println("Montando xml");

   String res = "";
  res += "<?xml version=\"1.0\"?>\n\r";
  res +="<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\">\n\r";
  res +="<S:Body>\n\r";
  res +="<ns2:sendPushNotification xmlns:ns2=\"http://impl.service.br.com/\">\n\r";
  res +="<msg>"+msg+"</msg>\n\r";
  res +="</ns2:sendPushNotification>\n\r";
Reply all
Reply to author
Forward
0 new messages