📄 saaj3.html
字号:
If the content you want to send is in a file, SAAJ provides an easy way to add it directly to the <code class="cCode">SOAPPart</code> object. This means that you do not access the <code class="cCode">SOAPBody</code> object and build the XML content yourself, as you did in the previous section. </p><a name="wp64121"> </a><p class="pBody">To add a file directly to the <code class="cCode">SOAPPart</code> object, you use a <code class="cCode">javax.xml.transform.Source</code> object from JAXP (the Java API for XML Processing). There are three types of <code class="cCode">Source</code> objects: <code class="cCode">SAXSource</code>, <code class="cCode">DOMSource</code>, and <code class="cCode">StreamSource</code>. A <code class="cCode">StreamSource</code> object holds content as an XML document. <code class="cCode">SAXSource</code> and <code class="cCode">DOMSource</code> objects hold content along with the instructions for transforming the content into an XML document.</p><a name="wp64122"> </a><p class="pBody">The following code fragment uses the JAXP API to build a <code class="cCode">DOMSource</code> object that is passed to the <code class="cCode">SOAPPart.setContent</code> method. The first three lines of code get a <code class="cCode">DocumentBuilderFactory</code> object and use it to create the <code class="cCode">DocumentBuilder</code> object <code class="cCode">builder</code>. Because SOAP messages use namespaces, you should set the <code class="cCode">NamespaceAware</code> property for the factory to true. Then <code class="cCode">builder</code> parses the content file to produce a <code class="cCode">Document</code> object.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();dbFactory.setNamespaceAware(true);DocumentBuilder builder = dbFactory.newDocumentBuilder();Document document = builder.parse("file:///music/order/soap.xml");DOMSource domSource = new DOMSource(document); <a name="wp79659"> </a></pre></div><a name="wp64124"> </a><p class="pBody">The following two lines of code access the <code class="cCode">SOAPPart</code> object (using the <code class="cCode">SOAPMessage</code> object <code class="cCode">message</code>) and set the new <code class="cCode">Document</code> object as its content. The method <code class="cCode">SOAPPart.setContent</code> not only sets content for the <code class="cCode">SOAPBody</code> object but also sets the appropriate header for the <code class="cCode">SOAPHeader</code> object.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">SOAPPart soapPart = message.getSOAPPart();soapPart.setContent(domSource);<a name="wp64125"> </a></pre></div><a name="wp64126"> </a><p class="pBody">The XML file you use to set the content of the SOAPPart object must include <code class="cCode">Envelope</code> and <code class="cCode">Body</code> elements, like this:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><SOAP-ENV:Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> ... </SOAP-ENV:Body></SOAP-ENV:Envelope><a name="wp79679"> </a></pre></div><a name="wp79678"> </a><p class="pBody">You will see other ways to add content to a message in the sections <a href="SAAJ3.html#wp78963">Adding a Document to the SOAP Body</a> and <a href="SAAJ3.html#wp80876">Adding Attachments</a>.</p><a name="wp78963"> </a><h3 class="pHeading2">Adding a Document to the SOAP Body</h3><a name="wp78968"> </a><p class="pBody">In addition to setting the content of the entire SOAP message to that of a <code class="cCode">DOMSource</code> object, you can add a DOM document directly to the body of the message. This capability means that you do not have to create a <code class="cCode">javax.xml.transform.Source</code> object. After you parse the document, you can add it directly to the message body:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">SOAPBody body = message.getSOAPBody();SOAPBodyElement docElement = body.addDocument(document);<a name="wp79703"> </a></pre></div><a name="wp80734"> </a><h3 class="pHeading2">Manipulating Message Content Using SAAJ or DOM APIs</h3><a name="wp80735"> </a><p class="pBody">Because SAAJ nodes and elements implement the DOM <code class="cCode">Node</code> and <code class="cCode">Element</code> interfaces, you have many options for adding or changing message content:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp80750"> </a><div class="pSmartList1"><li>Use only DOM APIs</li></div><a name="wp80751"> </a><div class="pSmartList1"><li>Use only SAAJ APIs</li></div><a name="wp80752"> </a><div class="pSmartList1"><li>Use SAAJ APIs and then switch to using DOM APIs</li></div><a name="wp80753"> </a><div class="pSmartList1"><li>Use DOM APIs and then switch to using SAAJ APIs</li></div></ul></div><a name="wp80754"> </a><p class="pBody">The first three of these cause no problems. Once you have created a message, whether or not you have imported its content from another document, you can start adding or changing nodes using either SAAJ or DOM APIs. </p><a name="wp80915"> </a><p class="pBody">But if you use DOM APIs and then switch to using SAAJ APIs to manipulate the document, any references to objects within the tree that were obtained using DOM APIs are no longer valid. If you must use SAAJ APIs after using DOM APIs, you should set all of your DOM typed references to null, because they can become invalid. For more information about the exact cases in which references become invalid, see the SAAJ API documentation.</p><a name="wp80897"> </a><p class="pBody">The basic rule is that you can continue manipulating the message content using SAAJ APIs as long as you want to, but once you start manipulating it using DOM, you should not use SAAJ APIs after that.</p><a name="wp80876"> </a><h3 class="pHeading2">Adding Attachments</h3><a name="wp79745"> </a><p class="pBody">An <code class="cCode">AttachmentPart</code> object can contain any type of content, including XML. And because the SOAP part can contain only XML content, you must use an <code class="cCode">AttachmentPart</code> object for any content that is not in XML format. </p><a name="wp79746"> </a><h4 class="pHeading3">Creating an AttachmentPart Object and Adding Content</h4><a name="wp64134"> </a><p class="pBody">The <code class="cCode">SOAPMessage</code> object creates an <code class="cCode">AttachmentPart</code> object, and the message also has to add the attachment to itself after content has been added. The <code class="cCode">SOAPMessage</code> class has three methods for creating an <code class="cCode">AttachmentPart</code> object.</p><a name="wp64135"> </a><p class="pBody">The first method creates an attachment with no content. In this case, an <code class="cCode">AttachmentPart</code> method is used later to add content to the attachment. </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">AttachmentPart attachment = message.createAttachmentPart();<a name="wp64136"> </a></pre></div><a name="wp64137"> </a><p class="pBody">You add content to <code class="cCode">attachment </code>with the <code class="cCode">AttachmentPart</code> method <code class="cCode">setContent</code>. This method takes two parameters, a Java <code class="cCode">Object</code> for the content, and a <code class="cCode">String</code> object that gives the content type. Content in the <code class="cCode">SOAPBody</code> part of a message automatically has a Content-Type header with the value <code class="cCode">"text/xml"</code> because the content has to be in XML. In contrast, the type of content in an <code class="cCode">AttachmentPart</code> object has to be specified because it can be any type.</p><a name="wp64138"> </a><p class="pBody">Each <code class="cCode">AttachmentPart</code> object has one or more headers associated with it. When you specify a type to the method <code class="cCode">setContent</code>, that type is used for the header <code class="cCode">Content-Type</code>. <code class="cCode">Content-Type</code> is the only header that is required. You may set other optional headers, such as <code class="cCode">Content-Id</code> and <code class="cCode">Content-Location</code>. For convenience, SAAJ provides <code class="cCode">get</code> and <code class="cCode">set</code> methods for the headers <code class="cCode">Content-Type</code>, <code class="cCode">Content-Id</code>, and <code class="cCode">Content-Location</code>. These headers can be helpful in accessing a particular attachment when a message has multiple attachments. For example, to access the attachments that have particular headers, you call the <code class="cCode">SOAPMessage</code> method <code class="cCode">getAttachments</code> and pass it the header or headers you are interested in.</p><a name="wp68183"> </a><p class="pBody">The following code fragment shows one of the ways to use the method <code class="cCode">setContent</code>. This method takes two parameters, the first being a Java <code class="cCode">Object</code> containing the content and the second being a <code class="cCode">String</code> giving the content type. The Java Object may be a <code class="cCode">String</code>, a stream, a <code class="cCode">javax.xml.transform.Source</code> object, or a <code class="cCode">javax.activation.DataHandler</code> object. The Java <code class="cCode">Object</code> being added in the following code fragment is a <code class="cCode">String</code>, which is plain text, so the second argument must be <code class="cCode">"text/plain"</code>. The code also sets a content identifier, which can be used to identify this <code class="cCode">AttachmentPart</code> object. After you have added content to <code class="cCode">attachment</code>, you need to add it to the <code class="cCode">SOAPMessage</code> object, which is done in the last line.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">String stringContent = "Update address for Sunny Skies " + "Inc., to 10 Upbeat Street, Pleasant Grove, CA 95439";attachment.setContent(stringContent, "text/plain");attachment.setContentId("update_address");message.addAttachmentPart(attachment);<a name="wp64140"> </a></pre></div><a name="wp76686"> </a><p class="pBody">The variable <code class="cCode">attachment</code> now represents an <code class="cCode">AttachmentPart</code> object that contains the string <code class="cCode">stringContent</code> and has a header that contains the string <code class="cCode">"text/plain"</code>. It also has a <code class="cCode">Content-Id</code> header with <code class="cCode">"update_address"</code> as its value. And <code class="cCode">attachment</code> is now part of <code class="cCode">message</code>.</p><a name="wp64144"> </a><p class="pBody">The other two <code class="cCode">SOAPMessage.createAttachment</code> methods create an <code class="cCode">AttachmentPart</code> object complete with content. One is very similar to the <code class="cCode">AttachmentPart.setContent</code> method in that it takes the same parameters and does essentially the same thing. It takes a Java <code class="cCode">Object</code> containing the content and a <code class="cCode">String</code> giving the content type. As with <code class="cCode">AttachmentPart.setContent</code>, the <code class="cCode">Object</code> may be a <code class="cCode">String</code>, a stream, a <code class="cCode">javax.xml.transform.Source</code> object, or a <code class="cCode">javax.activation.DataHandler</code> object. </p><a name="wp64145"> </a><p class="pBody">The other method for creating an <code class="cCode">AttachmentPart</code> object with content takes a <code class="cCode">DataHandler</code> object, which is part of the JavaBeans Activation Framework (JAF). Using a <code class="cCode">DataHandler</code> object is fairly straightforward. First you create a <code class="cCode">java.net.URL</code> object for the file you want to add as content. Then you create a <code class="cCode">DataHandler</code> object initialized with the <code class="cCode">URL</code> object:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">URL url = new URL("http://greatproducts.com/gizmos/img.jpg");DataHandler dataHandler = new DataHandler(url);AttachmentPart attachment = message.createAttachmentPart(dataHandler);attachment.setContentId("attached_image");message.addAttachmentPart(attachment);<a name="wp64146"> </a></pre></div><a name="wp64147"> </a><p class="pBody">You might note two things about the previous code fragment. First, it sets a header for <code class="cCode">Content-ID</code> with the method <code class="cCode">setContentId</code>. This method takes a <code class="cCode">String</code> that can be whatever you like to identify the attachment. Second, unlike the other methods for setting content, this one does not take a <code class="cCode">String</code> for <code class="cCode">Content-Type</code>. This method takes care of setting the <code class="cCode">Content-Type</code> header for you, which is possible because one of the things a <code class="cCode">DataHandler</code> object does is determine the data type of the file it contains.</p><a name="wp64148"> </a><h4 class="pHeading3">Accessing an AttachmentPart Object</h4><a name="wp64149"> </a><p class="pBody">If you receive a message with attachments or want to change an attachment to a message you are building, you will need to access the attachment. The <code class="cCode">SOAPMessage</code> class provides two versions of the method <code class="cCode">getAttachments</code> for retrieving its <code class="cCode">AttachmentPart</code> objects. When it is given no argument, the method <code class="cCode">SOAPMessage.getAttachments</code> returns a <code class="cCode">java.util.Iterator</code> object over all the <code class="cCode">AttachmentPart</code> objects in a message. When <code class="cCode">getAttachments</code> is given a <code class="cCode">MimeHeaders</code> object, which is a list of MIME headers, it returns an iterator over the <code class="cCode">AttachmentPart</code> objects that have a header that matches one of the headers in the list. The following code uses the <code class="cCode">getAttachments</code> method that takes no arguments and thus retrieves all of the <code class="cCode">AttachmentPart</code> objects in the <code class="cCode">SOAPMessage</code> object <code class="cCode">message</code>. Then it prints out the content ID, content type, and content of each <code class="cCode">AttachmentPart</code> object. </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">java.util.Iterator iterator = message.getAttachments();while (iterator.hasNext()) { AttachmentPart attachment = (AttachmentPart)iterator.next(); String id = attachment.getContentId(); String type = attachment.getContentType(); System.out.print("Attachment " + id + " has content type " + type); if (type == "text/plain") { Object content = attachment.getContent(); System.out.println("Attachment " + "contains:\n" + content); }}<a name="wp84434"> </a></pre></div><a name="wp77353"> </a><h3 class="pHeading2">Adding Attributes</h3><a name="wp75562"> </a><p class="pBody">An XML element may have one or more attributes that give information about that element. An attribute consists of a name for the attribute followed immediately by an equals sign (<code class="cCode">=</code>) and its value.</p><a name="wp75701"> </a><p class="pBody">The <code class="cCode">SOAPElement</code> interface provides methods for adding an attribute, for getting the value of an attribute, and for removing an attribute. For example, in the following code fragment, the attribute named <code class="cCode">id</code> is added to the <code class="cCode">SOAPElement</code> object <code class="cCode">person</code>. Because <code class="cCode">person</code> is a <code class="cCode">SOAPElement</code> object rather than a <code class="cCode">SOAPBodyElement</code> object or <code class="cCode">SOAPHeaderElement</code> object, it is legal for its <code class="cCode">Name</code> object to contain only a local name.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -