Blitzmax SOAP

BlitzMax Forums/BlitzMax Programming/Blitzmax SOAP

Leon Brown(Posted 2007) [#1]
Does anyone know if and how to use SOAP with BlitzMax to allow for interaction with online applications?


Brucey(Posted 2007) [#2]
I don't think it's safe to use *any* water-based products anywhere near your computer...


Leon Brown(Posted 2007) [#3]
ha ha ha... no, seriously :-). I'm interested in using it to integrate desktop interfaces to my web application. All shall be revealed soon.


Brucey(Posted 2007) [#4]
SOAP is just a "send and receive XML via HTTP" communication thingy.

So, I imagine all you need is:

1) Something to create/read XML (I would suggest getting yourself an XML module so you aren't reinventing wheels - there are two currently I know of, maxml and libxml. maxml is a pure BlitzMax implementation. Libxml is a cross-platform wrapper for the extremely full-featured Libxml2 library)

2) A way to send and receive via HTTP. Which, I believe, Max can do for you (via sockets etc).

Essentially, you send an HTTP request with your XML, and the server sends you back a response, also in XML.

A small guide here.


Aren't RSS feeds done via SOAP?


Brucey(Posted 2007) [#5]
I don't have any SOAP examples with my libxml module, I'm afraid.. but it can't be too hard to do it.


Leon Brown(Posted 2007) [#6]
Thanks. Do you know where I can find information about using the Blitz socket commands?


Brucey(Posted 2007) [#7]
There's a nice example here .
Not exactly what you need, but it'll set you off in the right direction.


Scott Shaver(Posted 2007) [#8]
here is some java code for connecting to a .NET SOAP Web Service

package com.foo.util.comm;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;

import com.foo.util.logging.CCLogger;

public class WebServiceAccess {
	private String m_NameSpace; // 
	private String m_ServiceAddress; // the address of the .asmx file
	public String m_ServiceName; // the name of the service

	/** Creates a new instance of WebbserviceAccess */
	public WebServiceAccess() {
		m_ServiceAddress = "";
		m_ServiceName = "";
		m_NameSpace = "";
	}

	public void setNameSpace(String nameSpace) {
		m_NameSpace = nameSpace;
	}

	public void setServiceAddress(String ServiceAddress) {
		m_ServiceAddress = ServiceAddress;
	}

	public void setServiceName(String ServiceName) {
		m_ServiceName = ServiceName;
	}

	public String sendParamerterizedSoapRequest(String xml, String cookies) throws Exception{
		return sendSoapRequest(m_ServiceAddress, xml, cookies);
	}
	
	public String sendNonParamerterizedSoapRequest(String xml, String cookies) throws Exception{
		return sendSoapRequest(m_ServiceAddress+"/"+m_ServiceName, xml, cookies);
	}
	
	private String sendSoapRequest(String postUrl, String xml, String cookies) throws Exception {
		int retry=0;
		CCLogger.getLogger().log(Level.INFO, "Sending: "+xml);
		while(retry<5) // try to recover from a connection reset error
		{
			try
			{
				// Create the connection where we're going to send the file.
				URL url = new URL(postUrl);
				URLConnection connection = url.openConnection();
				HttpURLConnection httpConn = (HttpURLConnection) connection;
		
				// After we copy it to a byte array, we can see
				// how big it is so that we can set the HTTP Cotent-Length
				// property. (See complete e-mail below for more on this.)
		
		//		FileInputStream fin = new FileInputStream(xmlFile2Send);
				ByteArrayInputStream str = new ByteArrayInputStream(xml.getBytes("ISO8859_1"));
				ByteArrayOutputStream bout = new ByteArrayOutputStream();
		
				// Copy the SOAP file to the open connection.
				copy(str, bout);
				str.close();
		
				byte[] b = bout.toByteArray();
		
				// Set the appropriate HTTP parameters.
				
				if(cookies!=null && cookies.length()>0)
					httpConn.setRequestProperty("Cookie", cookies);
				httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
				httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
				httpConn.setRequestProperty("SOAPAction", m_NameSpace+"/"+ m_ServiceName);
				httpConn.setRequestMethod("POST");
				httpConn.setDoOutput(true);
				httpConn.setDoInput(true);
		
				// Everything's set up; send the XML that was read in to b.
				OutputStream out = httpConn.getOutputStream();
				out.write(b);
				out.close();
		
				// Read the response and write it to standard out.
				InputStreamReader isr = null;
				boolean printOutputOnFailure = false;
				try{
					isr = new InputStreamReader(httpConn.getInputStream());
				}
				catch(IOException io){
					io.printStackTrace();
					isr = new InputStreamReader(httpConn.getErrorStream());
					printOutputOnFailure = true;
					com.cc.util.logging.CCLogger.getLogger().log(Level.SEVERE, "FAILURE on: "+m_ServiceName);
				}
				BufferedReader in = new BufferedReader(isr);
		
				String inputLine;
				StringBuffer sb = new StringBuffer(1000);
				while ((inputLine = in.readLine()) != null){
					sb.append(inputLine+"\n");
				}
				if(printOutputOnFailure) com.cc.util.logging.CCLogger.getLogger().log(Level.SEVERE, sb.toString());
				
				in.close();
				return sb.toString();
			}
			catch(SocketException x)
			{
				retry++;
				if(retry>5) // give up
					throw x;
				CCLogger.getLogger().log(Level.INFO, "Connection reset, retry number "+retry);
			}
		}
		return null;
	}

	// copy method from From E.R. Harold's book "Java I/O"
	private void copy(InputStream in, OutputStream out) throws IOException {

		// do not allow other threads to read from the
		// input or write to the output while copying is
		// taking place

		synchronized (in) {
			synchronized (out) {

				byte[] buffer = new byte[256];
				while (true) {
					int bytesRead = in.read(buffer);
					if (bytesRead == -1)
						break;
					out.write(buffer, 0, bytesRead);
				}
			}
		}

	}
}



and then you use it like this

WebServiceAccess wsa = new WebServiceAccess();
wsa.setServiceAddress(webserviceLocation);
wsa.setServiceName((String)webserviceServices.get(serviceName));
wsa.setNameSpace((String)webserviceServices.get(WS_XMLNS));
		
try {
   	if(hasParameters){
		return wsa.sendParamerterizedSoapRequest(xml, myCookie);
 	}
	return wsa.sendNonParamerterizedSoapRequest(xml,myCookie);
} 
catch (Exception ex1) 
{
ex1.printStackTrace();
return null;
}



where:

NameSpace is something like "http://www.foo.com
webserviceLocation is something like "http://ws.foo.com/myservice.asmx
serviceName is something like GetUserInfo
the xml might be something like:

<?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>
<GetUserInfo xmlns="http:\\www.foo.com" />
</soap:Body>
</soap:Envelope>



Scott Shaver(Posted 2007) [#9]
The cookies stuff is only used for piggybacking on an existing session in a .NET app. A somewhat more complete post about this on my web site at:

http://www.scottshaver2000.com/forum/viewtopic.php?p=695#695


Leon Brown(Posted 2007) [#10]
Thanks a lot for your help guys. I shall certainly take a look at the information provided :-)