技巧:用JAXM发送和接收SOAP消息

原创 2004年07月11日 13:52:00
Web 服务的基础在于以标准格式发送和接收消息以便使所有系统都能理解。通常,那种格式是简单对象访问协议(Simple Object Access Protocol (SOAP))。SOAP 消息可以手工生成和发送,但是用于 XML 消息传递的 Java API(JAXM)使许多必需步骤(如创建连接或创建并发送实际消息)自动化。这篇技巧文章记录了一个同步 SOAP 消息的创建和发送。

这个过程包括创建 SOAP 连接、创建 SOAP 消息、填充消息、发送消息、检索应答。

JAXM 可以作为 Java XML Pack(2002 年春季版)的一部分和 Java Web Services Developer Pack EA2(请参阅参考资料)的一部分而获得。后者还包含了一份 Tomcat Web 服务器以及样本应用程序的副本。那些样本 Web 服务之一作为本技巧文章中 SOAP 消息的目的地,这个例子中实际服务的内容和功能却不是很重要。

SOAP 消息结构


一个基本的SOAP消息由包含两个主要部分(报头和主体)的封套组成。应用程序决定如何使用这些部分,但整个消息必须遵循特定的 XML 结构,例如:

样本 SOAP 消息 <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:Header/> <soap-env:Body> <cal:schedule xmlns:cal="http://www.example.com/calendar"> <cal:newitem> <cal:eventDate>4/10/2002</cal:eventDate> <cal:title>Fun With Frogs</cal:title> </cal:newitem> </cal:schedule> </soap-env:Body> </soap-env:Envelope>


在这个例子中,报头为空,而主体包含目的地为一个日历应用程序的信息。

请注意这个消息的结构。Envelope 包含 Header 和 Body 元素,而三者全都是 http://schemas.xmlsoap.org/soap/envelope/ 名称空间的一部分。整个消息将通过一个 SOAP 连接发送到一个 Web 服务中。

创建连接和消息


第一步是创建整个类和连接:

创建连接

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


SOAP消息可以通过使用SOAPConnection直接发送,或使用消息传递提供程序间接发送。在这个例子中,应用程序通过使用工厂(factory)创建 SOAPConnection 对象。

工厂也创建消息本身:

创建消息对象

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


首先,通过使用 MessageFactory 来创建消息本身。这个消息已包含如 envelope 和 header 等基本部分的空白版本。SOAPPart 包含 envelope,而 envelope 包含主体。同时创建所需对象(如 SOAPBody)的引用。

接着,填充 SOAPBody:

填充主体 ... 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("schedule" , "cal", "http://www.example.com/calendar")); //Add content bodyElement.addChildElement("cal:newitem").addTextNode("contentHere"); //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.getMessage()); } } }
SOAP 消息的主体就象任何其它 XML 元素,您可以在其中添加子元素(如 schedule 元素)。通常,您可以使用 addChildElement(elementname),但是这里演示的 envelope.createName() 方法使用用于数据或有效负载的名称空间声明简化了元素的创建。的确,创建 schedule 元素从而创建了 bodyElement SOAPElement 对象。然后,bodyElement 对象可以给其自己的子元素 cal:newitem 添加其自己的文本节点。通过这种方式,您可以象构建任何其它 XML 文档一样构建 XML 结构。

然而,使用 JAXM,您也有机会通过使用外部文件直接创建消息的 SOAPPart。例如,第一个清单中的 XML 结构保存在文件 prepped.msg 中,而且可以调用它来替代手工构建文档。

从外部文件创建消息 ... 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 消息。

发送消息

对于同步消息,发送 SOAP 消息和接收应答是在单个步骤中发生的:

发送消息 ... import javax.xml.messaging.URLEndpoint; 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 URLEndpoint destination = new URLEndpoint("http://localhost:8080/jaxm-simple/receiver"); //Send the message SOAPMessage reply = connection.call(message, destination); //Close the connection connection.close(); ... } }


实际的消息是使用 call() 方法发送的,该方法把消息本身和目的地作为参数,然后返回第二个 SOAPMessage 作为应答。目的地必须是一个 Endpoint 对象,或者是这个例子中的 URLEndpoint。这个示例使用来自 JWSDP 的一个样本 servlet,它只用于获取响应。

call() 方法一直处于阻塞状态,直到它接收到返回的 SOAPMessage 为止。

响应


返回的 SOAPMessage — reply — 是 SOAP 消息,它与已发送的消息格式相同,因此可以象操作任何其它 XML 消息那样操作它。SOAP 允许您通过使用 XSLT 直接转换应答:

读取响应 ... 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(); ... } }


象在任何 XSLT 应用程序中那样创建 Transformer 对象。在这个例子中,我们只希望输出内容,所以没有用到样式表。这里,内容本身就是消息的整个 SOAP 部分(与可能包含附件的 SOAP 消息本身不同)。您还可以在处理之前抽取封套和主体。这个例子中的结果只是 System.out,但它可以是通常用于转换的任何选择。照常进行转换。

78472.gif


图 1. SOAP 请求和响应


下一步


虽然本示例中的端点是提供静态响应的 servlet,但是实际的响应取决于服务的功能和请求的性质。同时,虽然本篇技巧文章演示了消息的同步发送和接收,但是通过使用 ProviderConnection 对象而不是 SOAPConnection,JAXM 允许使用消息传递提供程序进行异步发送。该提供程序一直保存这个消息,直到成功发送消息为止。

webservice入门笔记二soap消息的处理

Soap消息的处理 首先,复习下,创建一个webservice服务。新建一个java工程 Soap。接口、接口、服务类分别如下: packagecom.zhutulang.soap; import...
  • zhutulang
  • zhutulang
  • 2016年04月11日 21:23
  • 1557

使用SAAJ发送和接收SOAP消息

在本技巧中,作者和开发人员 Nicholas Chase 向您展示了如何使用 SOAP with Attachments API for Java (SAAJ),从而简化创建和发送SOAP消息的过程。...
  • ren_it
  • ren_it
  • 2007年10月22日 14:03
  • 391

用httpPost对Json发送和接收的例子

HTTPPost发送JSON: private static final String APPLICATION_JSON = "application/json"; priva...
  • CHS007chs
  • CHS007chs
  • 2016年07月20日 16:49
  • 380

Socket编程之UDP发送、接收编程

UDP 用最通俗的话讲,所谓UDP,就是发送出去就不管的一种网络协议。因此UDP编程的发送端只管发送就可以了,不用检查网络连接状态。下面用例子来说明怎样编写UDP,并会详细解释每个API和数据类型。 ...
  • zyllong
  • zyllong
  • 2014年12月15日 17:02
  • 3700

SOAP消息头的处理

SOAP消息头通常包含与消息体或SOAP处理(应用)方式相关的信息,比如消息路径、数字签名、认证信息,消息关联性信息、消息体的加密公匙等等。 下面我们以一个简单的权限认证的示例,来讲解如何添加和...
  • linjingj
  • linjingj
  • 2014年01月30日 10:10
  • 3064

SOAP消息创建

看了SOAP消息分析之后,大家对soap消息应该有了一个初步的认识,那么怎样自己编写一个soap消息呢? 先来创建一个简单的soap消息: @Test public void test...
  • u012702547
  • u012702547
  • 2015年05月11日 11:20
  • 6527

发送/接收数据包与发送/接收字节的区别.

    这几天第一次遇到了这样的问题,网络连接发送和接收的数据量特别大,之前我用自己的台式电脑,后来帮我朋友弄手提电脑,发现接收和发送的数据量特别地大,刚开始没注意看是接收数据包还是接收字节,以为是电...
  • oxlshmily
  • oxlshmily
  • 2008年05月10日 00:47
  • 3430

使用UDP协议发送和接收数据

首选引用以下两个: using System.Net; using System.Net.Sockets; //获取机机IP地址: IPHostEntry ihe = Dns.GetHostB...
  • kaiyong
  • kaiyong
  • 2013年09月04日 08:44
  • 1582

CXF系列之SOAP消息格式

我们从前面了解 WebService 使用 HTTP 协议传输消息,消息格式使用 SOAP,那么在客户端和服务器端传输的 SOAP 消息是什么样子的呢?下面我们将服务端 SoapServer.java...
  • u013313550
  • u013313550
  • 2016年11月24日 15:43
  • 1017

SOAP消息的创建、传递和处理(MESSAGE方式)

private String ns = "http://service.soap.org/"; private String wsdlUrl = "http://localhost:8989/ms?w...
  • linjingj
  • linjingj
  • 2014年01月30日 10:10
  • 8215
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:技巧:用JAXM发送和接收SOAP消息
举报原因:
原因补充:

(最多只允许输入30个字)