axis2 soap

来源:互联网 发布:淘宝ppt 编辑:程序博客网 时间:2024/05/07 11:35

单向服务

继续讨论之前,让我们了解一下处理单向服务(而非请求/响应服务)时涉及到的不同之处。

服务

创建单向服务非常简单。此过程与创建请求/响应服务完全类似,至少不会实际返回任何内容。例如,可以为 CMSService类创建 addArticle 操作,如图 29 中所示。


清单 29. CMSServiceclass 中的 addArticle 操作
...    private Integer articleCount(String catId){...    }    public void addArticle(OMElement element)                              throws XMLStreamException{       element.build();       System.out.println(element);    }}

在 services.xml 文件中,将 addArticle 操作指定为“in only”操作,因此不会等待返回任何内容,但即使这样,也能看到会实际发生一些事项,会在命令行输出接收到的有效负载。您将在 Geronimo 窗口中看到此信息。

在实际应用程序中,此方法将从有效负载提取信息,并会实际添加到某种类型的数据库或其他存储库。

客户机

此服务的客户机也与请求/响应服务所使用的服务类似(请参见清单 30)。


清单 30. 创建客户机
                    import org.apache.axis2.addressing.EndpointReference;import org.apache.axis2.client.Options;import org.apache.axis2.client.ServiceClient;import org.apache.axis2.om.OMElement;import org.apache.axis2.SOAP.SOAPFactory;import org.apache.axis2.om.OMAbstractFactory;import org.apache.axis2.om.OMNamespace;public class AddArticleClient {    private static EndpointReference targetEPR =          new EndpointReference(             "http://localhost:8080/axis2/services/CMSService");    private static OMElement getOMElement(){        SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();        OMNamespace omNs = fac.createOMNamespace(                "http://daily-moon.com", "cms");        OMElement method = fac.createOMElement("addArticle", omNs);        OMElement category = fac.createOMElement("category", omNs);        category.setText("classifieds");        OMElement subcategory =                         fac.createOMElement("subcategory", omNs);        category.setText("wantads");        OMElement adtext = fac.createOMElement("article", omNs);        adtext.setText("Do you  have good head for numbers"+              " and a great deal of patience?  Do you like"+              " to sit for hours sorting objects by their"+              " size?  If so, then you could be the"+              " next goober counter in the world famous"+              " Murphy Brothers peanut factory. "+              " Willingness to dress up as our mascot"+              " helpful, but not required.");        method.addChild(category);        method.addChild(subcategory);        method.addChild(adtext);         return method;    }    public static void main(String[] args) {        try {            OMElement payload = AddArticleClient.getOMElement();            ServiceClient serviceClient = new ServiceClient();            Options options = new Options();            serviceClient.setOptions(options);            options.setTo(targetEPR);            serviceClient.fireAndForget(payload);        } catch (AxisFault axisFault) {            axisFault.printStackTrace();        }    }}

尽管有效负载不同,但正如您在 getOMElement() 方法中看到的,编程方面目前的唯一真正的更改是使用fireAndForget() 方法替代 sendReceive() 方法。此方法并不会返回响应。

如果运行此客户机,应该在 Geronimo 窗口中看到与图 5 中所示类似的输出。


图 5. 命令行输出

命令行输出 

通过 GET 访问服务

在 SOAP 1.2 推出之前,使用 HTTP 访问基于 SOAP 的 Web 服务的唯一方法是使用 POST 请求。您将需要创建能创建POST 请求并使用 SOAP 消息作为请求的内容的客户机。不过,SOAP 1.2 定义了使用 GET 请求访问基于 SOA 的 Web 服务的方法。

GET 与 POST 对比

继续我们的讨论之前,务必了解通过 HTTP 的 GET 和 POST 请求的区别。尽管很多 Web 程序员所进行的处理似乎表明二者之间是可以互换的,但实际上二者的用途并不相同。GET 中的所有关于所请求的资源的信息都包含在 URL(通常作为参数),仅用于等幂请求。这些请求是没有“副作用”的请求。也就是说,应该能够数十次、数百次、数千次地调用这个请求,但这个请求不会更改任何东西。例如,请求 Albuquerque 的当前气温的 Web 请求就是等幂请求。而将注释传入到博客数据库的 Web 请求则不是。

这是因为 GET 请求可以添加到用户的书签,能在不会引发警告的情况下进行访问。还可以对其进行引用,而不会引发警告。另一方面,POST 请求将其信息包含在请求的正文中,因此很难进行随机的重复。

就 SOAP 而言,这意味着应该能够对仅检索信息而不进行更改的 SOAP 请求使用 GET。对于进行更改的任何操作,仍然都应使用 POST

访问服务

在 Axis2 中,可以生成 GET 请求,服务器会将其转换为 SOAP 消息,然后将有效负载作为结果返回。例如,请将浏览器指向清单 31 中所示的位置。


清单 31. 访问服务
                    http://localhost:8080/axis2/services/CMSService/getNumberOfArticles?category=classifieds

如果使用 0.94 版,将看到清单 32 中所示的响应。


清单 31. SOAP 有效负载响应
                    <resp:numberOfArcticles>42</resp:numberOfArcticles>

不过,这并不十分准确。根据 SOAP 1.2 建议规范,应该能够看到整个 SOAP 响应。这在 Axis2 将来的版本中可能会发生更改。

处理附件

简单 SOAP 消息的另一个变体是附件。对于附件,多年来人们早已耳熟能详,但由于现在某些扩展规范要求使用附件,因此您必须对其进行处理。

二进制数据和 XML

尽管 XML 是基于文本的格式,但却不能忽略实际上是采用二进制进行表示的。因为这样,将会有需要向 Web 服务传递或从其检索二进制信息的情况。

可以采用两种方式中的一种来处理这种情况。第一种选择是将二进制数据实际包含在您的文档中。这种情况的一个例子是将 Microsoft Word 文档另存为 XML 文件时。如果在该文档中嵌入了任何图形,Word 会将其作为二进制数据嵌入到 XML 文档中(采用 Base64 编码)。第二种选择是直接引用该数据,以便处理该文档的应用程序能够找到此数据。一个极为常见的例子是 Web 浏览器以及其处理从 XHTML 文件引用的图像的方式。XHTML 文本包含一个 img 元素(或者,采用了更为先进的技术,则为 object 元素),该元素包含一个 src 属性,其中有指向实际数据的 URL。应用程序可以随后从该位置加载数据并相应地进行使用。

SOAP 文档也是这样。假如,如果向基于 SOAP 的服务提交了一个图像,有两个选择。可以将该数据嵌入在有效负载中,或可以想办法引用该数据。曾经由于涉及到带宽的一些问题对此进行过讨论。

XML 二进制优化打包

XML 已经比二进制对应项冗长得多了。正因为如此,它将使用更多的带宽。那么,当考虑使用向 XML 文本文档添加二进制数据时的首选方法(将其编码为 Base64)时,会由于两个或更多的因素而导致其尺寸增大,这就带来了一个非常实际的问题。

事实上,在过去的两三年,曾经有很多人强烈地批评缺乏对二进制数据的实时支持,几乎充斥着不满的声音,最终 W3C 开始着手处理这个问题。其工作的成果就是 XML 二进制优化打包(XML-binary Optimized Packages,XOP)。此协议提供了在 XML 文档中可靠地引用外部数据的方法。例如,SOAP with Attachments 规范规定二进制数据可以作为多部分 MIME 文档的的一部分发送,由 XML 数据组成第一部分,而二进制数据作为附加部分添加到其中。这样做的问题在于,尽管您的程序可能知道数据存在,但文档并不知道这一点。同时,还不允许对文档进行选择性优化或对包含二进制数据的现有文档进行回溯处理。

XOP 通过提供一个特殊的机制来改进这种情况,利用这种机制可选择性地提取要优化的信息,将其添加到多部分 MIME 消息中(其中也包括您的 SOAP 消息)并显式地对其进行引用。让我们看一个例子。

例如,假定员工不想将新文章作为文本元素添加,而希望将其作为二进制文档从字处理程序添加。如果将该内容包含在消息体中,将十分混乱,如清单 33 中所示:_


清单 33. 添加二进制文档
                    <?xml version='1.0' ?><env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">  <env:Header> </env:Header> <env:Body>  <cms:addArticle xmlns:cms="http://www.daily-moon.com/cms">    <cms:category>classifieds</category>    <cms:subcategory>forsale</cms:subcategory>    <cms:articleHeadline><cms:articleHeadline>    <cms:articleText>wvetwenptiubnweoirntuwopeirt4m[456n09ew7nvsa0tv043u6y304o5mu60ew9rebtm45bm4-69nw-0er9utnv3094nb-2620495u6-49kv6-m34956h-wb09emjb-0n67u-340v,=qw-enr7w8b64b03278-ANDLOTSMOREBASE64ENCODEDDATAHERE</cms:articleText>  </cms:addArticle> </env:Body></env:Envelope>

相反,XOP 规定对数据进行提取,然后使用一个引用其新位置的 Include 元素将其替换,如清单 34 中所示。


清单 34. 使用 XOP
                    MIME-Version: 1.0Content-Type: Multipart/Related;boundary=MIME_boundary;    type="application/xop+xml";    start="<soapmsg.xml@daily-moon.com>";    start-info="text/xml"Content-Description: An XML document with binary data in it--MIME_boundaryContent-Type: application/xop+xml;     charset=UTF-8;     type="text/xml"Content-Transfer-Encoding: 8bitContent-ID: <soapmsg.xml@daily-moon.com><env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope">  <env:Header> </env:Header> <env:Body>  <cms:addArticle xmlns:cms="http://www.daily-moon.com/cms">    <cms:category>classifieds</category>    <cms:subcategory>forsale</cms:subcategory>    <cms:articleHeadline><cms:articleHeadline>    <cms:articleText><xop:Include   xmlns:xop='http://www.w3.org/2004/08/xop/include'   href='cid:http://daily-moon.com/tbird.doc'/></cms:articleText>  </cms:addArticle> </env:Body></env:Envelope>--MIME_boundaryContent-Type: application/vnd.oasis.openofficeContent-Transfer-Encoding: binaryContent-ID: <http://daily-moon.com/tbird.doc>// binary octets for the word processing file--MIME_boundary--

请注意,Include 元素中指定的位置与 Content-ID 减去协议 cid: 的值匹配。现在要发送的是此消息,而不是纯文本 SOAP 消息。

SOAP、二进制数据和 Axis2

在 SOAP 文档中使用 XOP 的过程称为 MTOM(即 SOAP 消息传输优化机制——Message Transmission Optimization Mechanism)。Axis2 提供了使用 SOA 数据的这个方法的支持,但必须确保对应用程序进行了恰当配置。

具体来说,您必须在 axis2.war 文件内的 axis2.xml 文件中启用此支持(请参见清单 35)。


清单 35. 将 XOP 与 Axis2 一起使用
                    <axisconfig name="AxisJava2.0">    <!-- ================================================= -->    <!-- Parameters -->    <!-- ================================================= -->    <parameter name="hotdeployment" locked="false">true</parameter>    <parameter name="hotupdate" locked="false">true</parameter>    <parameter name="enableMTOM" locked="false">true</parameter>     <!-- Uncomment this to enable REST support -->    <!--    <parameter name="enableREST" locked="false">true</parameter>-->    <parameter name="userName" locked="false">admin</parameter>    <parameter name="password" locked="false">axis2</parameter>...

如果有必要,可以提取 axis2.war 文件,进行此更改,然后将其重新压缩成 .war 文件。

要替换 Axis2 应用程序,请使用清单 36 中所示的 URL 访问 Geronimo 控制台。


清单 36. Geronimo 控制台
                    http://localhost:8080/console

作为 system/manager 登录,并单击 Application>Web App WARs,然后卸载并重新安装 Axis2 应用程序。(请记住,执行此步骤后,必须重新加载 Web 服务。)

以编程方式使用 MTOM 不在本教程的讨论范围之内,但可以在参考资料部分获取有关此主题的更多信息。只是要注意,在 Axis2 的 0.95 版之前的版本上可能不会按照预期工作,因为该版本中包含了 SOAP with Attachments API for Java (SAAJ) 实现。