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