使用SAAJ发送和接收SOAP消息
2007-10-22 14:03
459 查看
在本技巧中,作者和开发人员 Nicholas Chase 向您展示了如何使用 SOAP with Attachments API for Java (SAAJ),从而简化创建和发送SOAP消息的过程。
Web 服务的基础是以标准格式发送和接收消息,这样所有系统都可以理解消息。通常情况下,这种标准格式是 SOAP。SOAP 消息可以手工生成和发送,但 SOAP with Attachments API for Java (SAAJ)—— Java API for XML Messaging (JAXM)的一个分支——能够使许多必需的步骤变得自动化,例如创建连接,或者创建和发送实际消息。本技巧介绍了同步 SOAP 消息的创建和发送。
该过程包括 5 个步骤:
1. 创建 SOAP 连接
2. 生成 SOAP 消息
3. 填充消息
4. 发送消息
5. 检索响应
SAAJ 是 Java Web Services Developer Pack 1.2 的一部分(参见 参考资料)。这个软件包还包含了 Tomcat Web 服务器(因此您就可以建立自己的服务)和例子应用程序。
安装问题
安装 Java Web Services Developer Pack 1.2 是很容易的——只要通过包含的 Tomcat Web 服务器发送消息即可。要通过独立的应用程序发送消息,像我这里所做的一样,需要采取以下步骤:
从网址 http://java.sun.com/webservices/downloads/webservicespack.html下载 JWSDP1.2。
将软件安装到相应目录中。
如果您正使用 Java 1.4,需要用下载的软件覆盖相关的 XML 类。创建以下目录:
并复制目录
中的文件到该目录下。(JAVA_HOME和JWSDP_HOME 分别表示 Java 安装以及 JWSDP 安装的目录。)
将下列文件加入 classpath 中:
<JWSDP_HOME>/saaj/lib/saaj-api.jar
<JWSDP_HOME>/saaj/lib/saaj-impl.jar
<JWSDP_HOME>/jwsdp-shared/lib/commons-logging.jar
<JWSDP_HOME>/jwsdp-shared/lib/mail.jar
<JWSDP_HOME>/jwsdp-shared/lib/activation.jar
<JWSDP_HOME>/jaxp/lib/endorsed/dom.jar
<JWSDP_HOME>/jaxp/lib/endorsed/xercesImpl.jar
<JWSDP_HOME>/jaxp/lib/endorsed/sax.jar
<JWSDP_HOME>/jaxp/lib/endorsed/xalan.jar
现在您就可以使用独立的程序从自己系统的任意位置发送消息了。
SOPA 消息的结构
首先来看消息自身的结构。一条基本的 SOAP 消息由带有两个主要部分的信封(envelope)构成:头部和主体。应用程序确定如何使用这些部分,但整个消息必须遵循特定的 XML 结构,例如:
清单1. 一条示例 SOAP 消息
这里,头部是空的,而主体包含了有效信息,或要传递的消息。在本例中,它是请求某本书价格的消息。
注意消息的结构。Envelope 包含 Header 和 Body 元素,这三者都是http://schemas.xmlsoap.org/soap/envelope/ namespace的一部分。应用程序使用 SOAPConnection 来发送消息。
创建连接和消息
第一步是要创建总体类和连接:
清单2. 创建连接
应用程序可以直接使用 SOAPConnnection 或间接使用消息提供者来发送 SOAP 消息,现在 SOAPConnection 已经是 SAAJ 包的一部分了,而消息提供者仍然属于 JAXM 包。在本例中,应用程序使用工厂创建 SOAPConnection 对象。
工厂还创建了消息自身:
清单3. 创建消息对象
首先,使用 MessageFactory 创建消息自身。这一消息已经包含了空的基本部分,比如
接着,填充 SOAPBody:
清单4. 填充主体
SOAP 消息的主体就好像是另一个 XML 元素,可以在其中添加孩子元素,比如 getPrice。然后就可以像处理典型的 DOM 元素一样,为它添加 isbn 元素和文本节点。
使用 SAAJ 还有可能使用外部文件来直接创建消息的 SOAPPart。例如,第一个程序清单中,prepped.msg 文件包含了 XML 结构,在手工建立文档的地方可以调用该文件:
清单5. 从一个外部文件创建消息
通常,StreamSource 类用作 XSL Transformation 的一部分,但在这儿可以简单地使用它来获得 FileInputStream。结果是一个 SOAP 消息已经就绪,可以发送了。
发送消息
对于同步消息,发送 SOAP 消息,并接收在同一步中发生的响应:
清单6. 发送消息
实际的消息是使用 call()方法发送的,该方法接收消息本身和目的地作为参数,并返回第二个 SOAPMessage 作为响应。在早期版本的 JAXM 中,目的地必须是一个 Endpoint 对象或一个 URLEndpoint,但现在它只要是一个对象就可以了。这个例子使用了由 XMethods 支持的“书价检验程序” Web 服务,该服务返回请求中给定 ISBN 的书的价格。
call()方法将会阻塞,直到它接收到返回的 SOAPMessage 为止。
响应
相应地,返回的 SOAPMessage 是一个与发送消息具有相同形式的 SOAP 消息,这样该消息操作时就可以像另一个 XML 消息一样。SOAP 允许直接使用 XSLT 来转换响应:
清单7.读取响应
像在任意 XSLT 应用程序中一样,创建 Transformer 对象。在本例中,只需要输出内容,因此没有样式表。这里,内容本身就是消息的整个 SOAP 部分(与 SOAP 消息本身相反,它可能包含附件)。您也可以在处理前提取信封和主体。在本例中,结果就是 System.out,但一般情况下,可以是一次转换可用的任意选择。像平常一样地进行转换。
图1. SOAP 请求和响应
接下来的步骤
这个简单的应用程序仅仅输出所接收到的消息,但是您可以同样简单地从 XML 文档中提取信息。同样,虽然这一技巧仅演示了消息的同步发送和接收,但是 JAXM API 也允许用于同步传送的消息提供者的使用,只是通过使用 ProviderConnection 对象而不是 SOAPConnection 进行。提供者保持消息,直到该消息成功传送为止。
JAXM 也允许配置文件的使用,配置文件可以简化特定 SOAP 消息的创建,比如 SOAP-RP 或 ebXML 消息。
Web 服务的基础是以标准格式发送和接收消息,这样所有系统都可以理解消息。通常情况下,这种标准格式是 SOAP。SOAP 消息可以手工生成和发送,但 SOAP with Attachments API for Java (SAAJ)—— Java API for XML Messaging (JAXM)的一个分支——能够使许多必需的步骤变得自动化,例如创建连接,或者创建和发送实际消息。本技巧介绍了同步 SOAP 消息的创建和发送。
该过程包括 5 个步骤:
1. 创建 SOAP 连接
2. 生成 SOAP 消息
3. 填充消息
4. 发送消息
5. 检索响应
SAAJ 是 Java Web Services Developer Pack 1.2 的一部分(参见 参考资料)。这个软件包还包含了 Tomcat Web 服务器(因此您就可以建立自己的服务)和例子应用程序。
安装问题
安装 Java Web Services Developer Pack 1.2 是很容易的——只要通过包含的 Tomcat Web 服务器发送消息即可。要通过独立的应用程序发送消息,像我这里所做的一样,需要采取以下步骤:
从网址 http://java.sun.com/webservices/downloads/webservicespack.html下载 JWSDP1.2。
将软件安装到相应目录中。
如果您正使用 Java 1.4,需要用下载的软件覆盖相关的 XML 类。创建以下目录:
<JAVA_HOME>/jre/lib/endorsed
并复制目录
<JWSDP_HOME>/jaxp/lib/endorsed
中的文件到该目录下。(JAVA_HOME和JWSDP_HOME 分别表示 Java 安装以及 JWSDP 安装的目录。)
将下列文件加入 classpath 中:
<JWSDP_HOME>/saaj/lib/saaj-api.jar
<JWSDP_HOME>/saaj/lib/saaj-impl.jar
<JWSDP_HOME>/jwsdp-shared/lib/commons-logging.jar
<JWSDP_HOME>/jwsdp-shared/lib/mail.jar
<JWSDP_HOME>/jwsdp-shared/lib/activation.jar
<JWSDP_HOME>/jaxp/lib/endorsed/dom.jar
<JWSDP_HOME>/jaxp/lib/endorsed/xercesImpl.jar
<JWSDP_HOME>/jaxp/lib/endorsed/sax.jar
<JWSDP_HOME>/jaxp/lib/endorsed/xalan.jar
现在您就可以使用独立的程序从自己系统的任意位置发送消息了。
SOPA 消息的结构
首先来看消息自身的结构。一条基本的 SOAP 消息由带有两个主要部分的信封(envelope)构成:头部和主体。应用程序确定如何使用这些部分,但整个消息必须遵循特定的 XML 结构,例如:
清单1. 一条示例 SOAP 消息
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Header /> <SOAP-ENV:Body> <ns1:getPrice xmlns:ns1="urn:xmethods-BNPriceCheck" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <isbn xsi:type="xsd:string">0672324229</isbn> </ns1:getPrice> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
注意消息的结构。Envelope 包含 Header 和 Body 元素,这三者都是http://schemas.xmlsoap.org/soap/envelope/ namespace的一部分。应用程序使用 SOAPConnection 来发送消息。
创建连接和消息
第一步是要创建总体类和连接:
清单2. 创建连接
import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPConnection; public class SOAPTip { public static void main(String args[]) { try { //First create the connection SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance(); SOAPConnection connection = soapConnFactory.createConnection(); //Close the connection connection.close(); } catch(Exception e) { System.out.println(e.getMessage()); } } } |
工厂还创建了消息自身:
清单3. 创建消息对象
import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPConnection; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPBody; public class SOAPTip { public static void main(String args[]) { try { //First create the connection SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance(); SOAPConnection connection = soapConnFactory.createConnection(); //Next, create the actual message MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage message = messageFactory.createMessage(); //Create objects for the message parts SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPBody body = envelope.getBody(); //Close the connection connection.close(); } catch(Exception e) { System.out.println(e.getMessage()); } } } |
envelope和
header。SOAPPart 包含了
envelope,而
envelope又包含了主体。创建对所需对象(比如 SOAPBody)的引用。
接着,填充 SOAPBody:
清单4. 填充主体
... import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPElement; public class SOAPTip { public static void main(String args[]) { try { ... //Create objects for the message parts SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPBody body = envelope.getBody(); //Populate the body //Create the main element and namespace SOAPElement bodyElement = body.addChildElement(envelope.createName("getPrice" , "ns1", "urn:xmethods-BNPriceCheck")); //Add content bodyElement.addChildElement("isbn").addTextNode("0672324229"); //Save the message message.saveChanges(); //Check the input System.out.println("//nREQUEST://n"); message.writeTo(System.out); System.out.println(); //Close the connection connection.close(); } catch(Exception e) { System.out.println(e.getMessa a0a9 ge()); } } } |
使用 SAAJ 还有可能使用外部文件来直接创建消息的 SOAPPart。例如,第一个程序清单中,prepped.msg 文件包含了 XML 结构,在手工建立文档的地方可以调用该文件:
清单5. 从一个外部文件创建消息
... import javax.xml.soap.SOAPElement; import java.io.FileInputStream; import javax.xml.transform.stream.StreamSource; public class SOAPTip { public static void main(String args[]) { ... //Create objects for the message parts SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPBody body = envelope.getBody(); //Populate the Message StreamSource preppedMsgSrc = new StreamSource( new FileInputStream("prepped.msg")); soapPart.setContent(preppedMsgSrc); //Save the message message.saveChanges(); ... } } |
发送消息
对于同步消息,发送 SOAP 消息,并接收在同一步中发生的响应:
清单6. 发送消息
... public class SOAPTip { public static void main(String args[]) { ... //Check the input System.out.println("//nREQUEST://n"); message.writeTo(System.out); System.out.println(); //Send the message and get a reply //Set the destination String destination = "http://services.xmethods.net:80/soap/servlet/rpcrouter"; //Send the message SOAPMessage reply = connection.call(message, destination); //Close the connection connection.close(); ... } } |
call()方法将会阻塞,直到它接收到返回的 SOAPMessage 为止。
响应
相应地,返回的 SOAPMessage 是一个与发送消息具有相同形式的 SOAP 消息,这样该消息操作时就可以像另一个 XML 消息一样。SOAP 允许直接使用 XSLT 来转换响应:
清单7.读取响应
... import javax.xml.transform.TransformerFactory; import javax.xml.transform.Transformer; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamResult; public class SOAPTip { public static void main(String args[]) { try { ... //Send the message SOAPMessage reply = connection.call(message, destination); //Check the output System.out.println("//nRESPONSE://n"); //Create the transformer TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); //Extract the content of the reply Source sourceContent = reply.getSOAPPart().getContent(); //Set the output for the transformation StreamResult result = new StreamResult(System.out); transformer.transform(sourceContent, result); System.out.println(); //Close the connection connection.close(); ... } } |
图1. SOAP 请求和响应
接下来的步骤
这个简单的应用程序仅仅输出所接收到的消息,但是您可以同样简单地从 XML 文档中提取信息。同样,虽然这一技巧仅演示了消息的同步发送和接收,但是 JAXM API 也允许用于同步传送的消息提供者的使用,只是通过使用 ProviderConnection 对象而不是 SOAPConnection 进行。提供者保持消息,直到该消息成功传送为止。
JAXM 也允许配置文件的使用,配置文件可以简化特定 SOAP 消息的创建,比如 SOAP-RP 或 ebXML 消息。
相关文章推荐
- 使用SAAJ发送和接收SOAP消息
- : 使用SAAJ发送和接收SOAP消息
- rabbitmq学习10:使用spring-amqp发送消息及异步接收消息
- Android非UI主线程中,若干普通Java线程使用Handler发送接收消息
- ASP.NET--使用Socket发送和接收消息[转载]
- 如何在WCF中用TcpTrace工具查看发送和接收的SOAP消息
- Webservice的wsdl文件解析与Soap消息的发送、接收(不生成java客户端代码)
- opensaml的SOAP消息发送和接收
- JMS_使用ActiveMQ实现消息的发送和接收
- 使用spring-rabbit测试RabbitMQ消息确认(发送确认,接收确认)
- QUdpSocket简单使用Demo(局域网内发送给所有客户端消息与接收)
- WebSphereMq使用JMS发送消息和接收消息
- activemq使用JMS发送消息和接收消息
- 使用JMS发送和接收text和Object类型的消息
- 使用Akka持久化——消息发送与接收
- rabbitmq学习9:使用spring-amqp发送消息及同步接收消息
- ActiveMQ的消息的(含附件)发送和接收使用
- 【Spring】使用Spring和AMQP发送接收消息(下)
- ROS_Kinetic_26 使用rosserial_windows实现windows与ROS master发送与接收消息
- IOS使用XMPP最新教程(六)发送和接收消息