Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1650009
  • 博文数量: 13833
  • 博客积分: 1041400
  • 博客等级: 大元帅
  • 技术积分: 127080
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-13 10:12
文章分类

全部博文(13833)

文章存档

2008年(13833)

我的朋友

分类:

2008-06-13 10:26:01

  本部分是apache axis用户指南的第二部分。 5.服务Styles---RPC,Document,Wrapped和消息 Axis支持四种样式的服务。 RPC服务使用SOAP RPC惯例和SOAP section 5的编码。Document服务部使用任何编码方式(所以,不会看到多饮用的对象序列化或者SOAP-style数组),但是使用XML<-->Java数据绑定。Wrapped服务和document服务相似,但是Wrapped服务不是将整个SOAPbody绑定到一个大的结构,而是将它分成很多个体参数。Message服务接受和返回任意SOAP Envelope中的XML,并不进行类型映射和数据绑定。 如果只想使用原始的XML作为SOAP Envelope的输入和输出,那么就是用message服务。 RFC服务 RFC服务是Axis的默认服务。它们在部署描述符中的定义为或者。RPC服务遵循SOAP RPC和编码规则,这意味着RPC服务的XML就像上面的echoString例子一样,每个RPC调用都作为操作名,包含的内部元素对应操作的参数。Axis会将XML反序列化成Java对象来适应服务,然后再将返回的Java对象进行序列化成XML返回。由于RPC服务默认使用soap section 5比阿玛规则,对象会通过multi-ref序列化,允许对对象图表进行编码。 Document/Wrapped服务 这两种服务很类似,都不对数据进行SOAP编码,而只是简单的XML Schema。在这两种情况中,Axis仍然对java表示与XML进行绑定,所以只需要处理Java对象,而不是直接处理XML结构。 下面是一个关于购买顺序的SOAP消息,用来说明两者的区别:                                    对于Document样式的服务,将会映射到一个如下的方法: public void method(PurchaseOrder po) 也就是说,整个元素作为方法的一个单独的bean对象参数,这个Bean类应该有三个成员属性。而对于wrapped样式的服务来说,将会映射到如下的方法: public void purchaseOrder(String item,int quality,String description) 注意在这种情况的大小写,元素是一个”wrapper”,只处理正确的操作。方法的参数就是unwrap外层元素后的每一个内层元素。 document或者wrapped样式的定义是在WSDD中定义的: for document style for wrapped style 当使用WSDL文档创建Web Service的时候,就不需要担心到底是哪种服务了。 Message服务 最后是Message样式的服务,当需要使Axis无效,将代码作为实际的XML查看而不是java对象的时候,就使用这种服务。 下面是四的message-style服务的方法的合法信号 public Element [] method(Element [] bodies); public SOAPBodyElement [] method (SOAPBodyElement [] bodies); public Document method(Document body); public void method(SOAPEnvelope req, SOAPEnvelope resp); 前两个将方法的数组传给方法DOM元素或者SOAPBody元素的数组-----这个数组包含中的每一个XML元素。 第三个方法传递一个DOM文档,这个文档表示,并期望同样的返回。 最后一个传递两个SOAPEnvelope对象来表示请求和响应消息,这意味着可以在服务方法中查看或者修改headers。 Message样例 在Axis的例子中,samples\message\MessageService.java就是一个Message服务的例子,服务的类是MessageService,包含一个公开方法,echoElement,符合上述中的第一个方法: public Element[] echoElements(Element[] elems) MsgProvider是一个handler,它调用echoElement()方法,传递一个org.w3c.dom.Element的数组作为参数,作为输入信息的SOAPbody的直接子元素。一般来说,这个数组会包含一个单独的Element(可能是一个XML文档的根元素),但是SOAP Body可以处理任意多个子元素。这个方法返回一个Element[]数组作为响应消息的SOAP Body。 package samples.message ;   import org.w3c.dom.Element; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.Name; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPBodyElement; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPElement;   /**  * Simple message-style service sample.  */ public class MessageService {     /**      * Service method, which simply echoes back any XML it receives.      *      * @param elems an array of DOM Elements, one for each SOAP body element      * @return an array of DOM Elements to be sent in the response body      */     public Element[] echoElements(Element [] elems) {         return elems;     }       public void process(SOAPEnvelope req, SOAPEnvelope resp) throws javax.xml.soap.SOAPException {     SOAPBody body = resp.getBody();     Name ns0 = resp.createName("TestNS0", "ns0", ");     Name ns1 = resp.createName("TestNS1", "ns1", ");     SOAPElement bodyElmnt = body.addBodyElement(ns0);     SOAPElement el = bodyElmnt.addChildElement(ns1);     el.addTextNode("TEST RESPONSE");     } } MessageService的WSDD文件内容如下:           注意这里使用的是style=”message”,而不是使用provider=”java:RPC”。message style告诉Axis本服务是由org.apache.axis.providers.java.MsgProvider来处理的,而不是org.apache.axis.providers.java.RPCProvider。 6.XML<---->Java数据映射 将Java类型映射到SOAP/XML类 互操作,或者叫interop,是各种SOAP实现之间的一个存在的挑战。如果期望服务在其他的平台和实现上也可以使用,需要理解这个概念。Axis中Java类型到WSDL/XSD/SOAP的映射由JAX-RPC规范确定。相关内容请参考JAX-RPC规范。 WSDL到Java的标准映射 xsd:base64Binary          byte[] xsd:boolean                     boolean xsd:byte                             byte xsd:dateTime                  java.util.Calendar xsd:decimal                      java.math.BigDecimal xsd:double                        double xsd:float                             float xsd:hexBinary                  byte[] xsd:int                                  int xsd:integer                         java.math.BigInteger xsd:long                             long xsd:QName                      javax.xml.namespace.QName xsd:short                            short xsd:string                            java.lang.String 如果在WSDL中声明了一个对象是nillable的,则调用者可以选择返回值为0,这样的话,原始数据类型可以使用它们的包装类代替,例如Byte、Double、Boolean。 SOAP编码数据类型 和XSD数据类型相对应的是SOAP ‘Section 5’数据类型,这些数据类型都是nillable的,所以总是可以和包装类映射。这些类型之所以存在是因为他们都支持ID和HREF属性,所以也用于当一个RPC编码的context来支持multi-ref序列化。 7.异常 一般来说,Axis将java.rmi.RemoteException映射成为SOAP Fault。这部分内容在笔者介绍的Axis2的文章中有比较详细的介绍,请参考。 8.Axis可以/不可以通过SOAP发送的内容 Java的集合框架元素,例如Hashtable,具有序列器,但是和其它的SOAP实现没有正式的交互操作能力,并且在SOAP规范中没有对应的复杂对象。最可靠的发送集合对象的办法就是使用数组。 没有预先注册的对象:不能发送任意的Java对象,并且期望它们可以被在服务器端被理解。在使用RMI的时候,可以发送和接受实现了Serializable接口的Java对象,那是由于双发都是使用Java。Axis值可以发送那么被Axis序列器注册的对象。文本后面会介绍如何使用BeanSerializer来序列化任何符合JavaBean规范的类。 远程引用:远程引用(Remote Reference)既不是SOAP规范的一部分,也不是JAX-RPC的一部分,所以不能返回对象的引用,然后期望调用者可以使用它作为SOAP调用的参数或者其他调用的参数。此时应该使用其他的方案,例如将他们存储在HashMap中,使用数字或者字符串键值来进行标识,这样就可以传递键值。 9.编码Beans---BeanSerializer Axis具有序列化和反序列化的能力,不需要编写代码,任何Java类,主要它遵守标准JavaBean的模式,那么就只需要告诉Axis Java类与XML Schema类型之间的映射,配置方式如下: 标签将一个Java类映射到一个XML QName。主要它包含两个重要的属性,qname和languageSpecificType。所以在上例中,将my.java.thingy类映射到XML QName:[someNamespace]:[local]。 下面看一个例子:BeanService.java package samples.userguide.example5;   public class BeanService {     public String processOrder(Order order)     {         String sep = System.getProperty("line.separator");         String response = "Hi, " + order.getCustomerName() + "!" + sep;         response += sep + "You seem to have ordered the following:" + sep;         String [] items = order.getItemCodes();         int [] quantities = order.getQuantities();         for (int i = 0; i < items.length; i++) {             response += sep + quantities[i] + " of item : " + items[i];         }         response += sep + sep +                     "If this had been a real order processing system, "+                     "we'd probably have charged you about now.";         return response;     } } 上面的代码中,Order类是一个JavaBean类。由于Order类不是一个基本类型,这样Axis就不能识别它,所以一个错误的wsdd是下面这样的:                      而正确的wsdd文件应该为下面的文件:                             运行的结果如下: 此时在Client类中需要添加如下的代码: QName    qn      = new QName( "urn:BeanService", "Order" ); call.registerTypeMapping(Order.class, qn,new org.apache.axis.encoding.ser.BeanSerializerFactory(Order.class, qn), new org.apache.axis.encoding.ser.BeanDeserializerFactory(Order.class, qn)); Axis允许用户编写自定义的序列器和反序列器,并提供了实现序列器和反序列器的工具。现在只需要查看DataSer/DataDeser类、BeanSerializer/BeanDeserializer、ArraySerializer/ArrayDeserializer以及org.apache.axis.encoding.ser包中的其他类。 部署自定义的映射----标签 在建立了自定义的序列器和反序列器后,需要告诉Axis这些序列器的应用范围,通过在WSDD中使用它: 管理员在2009年8月13日编辑了该文章文章。
-->
阅读(69) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~