Creating SOAP Messages Programmatically

In this tutorial we will learn how to create a javax.xml.soap.SOAPMessage programmatically using SOAPBody and SOAPElement objects and how to create one from a String. First of all the javax.xml.soap.SOAPMessage is the root class for all SOAP messages. As transmitted on the “wire”, a SOAP message is an XML document or a MIME message whose first body part is an XML/SOAP document.
A SOAPMessage object consists of a SOAP part and optionally one or more attachment parts. The SOAP part for a SOAPMessage object is a SOAPPart object, which contains information used for message routing and identification, and which can contain application-specific content. All data in the SOAP Part of a message must be in XML format.  The following code shows how you can code a SOAP Request:

private SOAPMessage createSOAPRequest() throws Exception
{
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();
        SOAPPart soapPart = soapMessage.getSOAPPart();

        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration("acme", "http://samples.saaj.jms");

        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement("employee", "acme");
        SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("id", "acme");
        soapBodyElem1.addTextNode("10");

        soapMessage.saveChanges();

        System.out.println("Request SOAP Message = ");
        soapMessage.writeTo(System.out);
        System.out.println();
        return soapMessage;
}

This is the SOAPMesage XML that will be created:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acme="http://samples.saaj.jms">
   <SOAP-ENV:Header />
   <SOAP-ENV:Body>
      <acme:employee>
         <acme:id>10</acme:id>
      </acme:employee>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The following code, shows how to parse into a String the soapMessage object:

ByteArrayOutputStream outstream = new ByteArrayOutputStream();
soapMessage.writeTo(outstream);
String strMsg = new String(outstream.toByteArray());

Create a SOAPMessage from an XML String

Another strategy for creating a SOAPMessage implies using a SAXParser to create the SOAP Message from an XML String:

package org.example;

import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import javax.xml.parsers.*;
import javax.xml.soap.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class CreateSOAPfromXML {

public static SOAPElement createSOAPElementFromXMLString(String xmlString)
       throws ParserConfigurationException, IOException, SAXException
   {
       StringReader stringReader = new StringReader(xmlString);
       InputSource inputSource = new InputSource(stringReader);
       SAXParserFactory factory = SAXParserFactory.newInstance();
       factory.setNamespaceAware(true);
       SAXParser parser = factory.newSAXParser();
       SoapElementSaxHandler handler = new SoapElementSaxHandler();
       parser.parse(inputSource, handler);
       return handler.getSOAPElement();
   }

}

And here is the SoapElementHandler required for this class:

package org.example;

import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.soap.*;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SoapElementHandler extends DefaultHandler {
	private HashMap prefixURIMapping;
	private ArrayList uris;
	private SOAPElement rootElement;
	private SOAPElement currentElement;
	private SOAPFactory soapFactory;

	public SoapElementHandler() {
		prefixURIMapping = new HashMap();
		uris = new ArrayList();
		rootElement = null;
		currentElement = null;
	}

	public SOAPElement getSOAPElement() {
		return rootElement;
	}

	public void startDocument() throws SAXException {
		try {
			soapFactory = SOAPFactory.newInstance();
		} catch (SOAPException e) {
			throw new SAXException("Error: Can't create a SOAPFactory instance", e);
		}
	}

	public void startPrefixMapping(String prefix, String uri) {
		prefixURIMapping.put(uri, prefix);
		uris.add(uri);
	}

	public void characters(char ch[], int start, int length) throws SAXException {
		String str = String.valueOf(ch);
		if (length > 0)
			try {
				currentElement.addTextNode(str.substring(start, start + length));
			} catch (SOAPException e) {
				throw new SAXException("Error: Can't add a text node into SOAPElement from text", e);
			}
	}

	public void endElement(String uri, String localName, String qName) {
		if (currentElement != rootElement)
			currentElement = currentElement.getParentElement();
	}

	public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
		String prefix = (String) prefixURIMapping.get(namespaceURI);
		try {
			if (rootElement == null && currentElement == null) {
				rootElement = soapFactory.createElement(localName, prefix, namespaceURI);
				currentElement = rootElement;
			} else {
				currentElement = currentElement.addChildElement(localName, prefix, namespaceURI);
			}
			if (uris.size() > 0) {
				for (int i = 0; i < uris.size(); i++) {
					String uri = (String) uris.get(i);
					String pre = (String) prefixURIMapping.get(uri);
					currentElement.addNamespaceDeclaration(pre, uri);
				}

				uris.clear();
			}
			for (int i = 0; i < atts.getLength(); i++) {
				javax.xml.soap.Name attriName;
				if (atts.getURI(i) != null) {
					String attriPre = (String) prefixURIMapping.get(atts.getURI(i));
					attriName = soapFactory.createName(atts.getLocalName(i), attriPre, atts.getURI(i));
				} else {
					attriName = soapFactory.createName(atts.getLocalName(i));
				}
				currentElement.addAttribute(attriName, atts.getValue(i));
			}

		} catch (SOAPException e) {
			throw new SAXException(e);
		}
	}

}
Found the article helpful? if so please follow us on Socials