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);
}
}
}