天道酬勤

点点滴滴的足迹,幻化成漫天的云彩
posts - 22, comments - 0, trackbacks - 0, articles - 2
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

AXIS技术的一个问题

Posted on 2011-07-17 01:01 匆匆过客 阅读(4400) 评论(0)  编辑  收藏 所属分类: Java
前天做技术交流,有一位同仁针对下面的一段AXIS客户端代码提出了这样的问题:QName qname=new QName("SparePartDetails","SparePartBean");这2个参数是什么意义?

 1         String endpointURL = "http://localhost:8080/ws/services/SparePartService";
 2         String methodName = "getSparepart";
 3 
 4         Service service = new Service();
 5         Call call = (Call) service.createCall();
 6         call.setTargetEndpointAddress(new java.net.URL(endpointURL));
 7         call.setOperationName(new QName("SparePartService", methodName));
 8 
 9         call.addParameter("sku", XMLType.XSD_STRING, ParameterMode.IN);
10 
11         QName qname = new QName("SparePartDetails""SparePartBean");
12         Class cls = org.bluebear.ws.advanced.customdatatype.SparePartBean.class;
13         call.registerTypeMapping(cls, qname, BeanSerializerFactory.class, BeanDeserializerFactory.class);
14         call.setReturnType(qname);
15 
16         Object[] params = new Object[] { "222222" };
17         SparePartBean spBean = (SparePartBean) call.invoke(params);
18 
19         System.out.println(spBean);

当时有的同仁回答说是根据WSDD中的beanMapping中的定义来确定的。这句话本身没有错,可是如果Service是.Net的语言写的呢?或者Service不是通过AXIS来发布的呢?是否也有WSDD?

1     <service name="SparePartService" provider="java:RPC">
2         <parameter name="className"
3                    value="org.bluebear.ws.advanced.customdatatype.service001.SparePartService" />
4         <parameter name="allowMethods" 
5                    value="getSparePart" />
6         <beanMapping qname="blueBearNS:SparePartBean"
7                      xmlns:blueBearNS="SparePartDetails"
8                      languageSpecificType="java:org.bluebear.ws.advanced.customdatatype.SparePartBean" />
9     </service>

这个问题存留于我的脑海中。对于客户端而言,只是需要知道如何将返回的SOAP XML 信息转换成相应的JavaBean就可以了。对于Service而言,只是需要将JavaBean转换成SOAP XML。所以客户端的代码应该和SOAP XML一致。为此我特地研究了2个方面的问题:
1. QName的Constructor
/**
     * <p><code>QName</code> constructor specifying the Namespace URI
     * and local part.</p>
     *
     * <p>If the Namespace URI is <code>null</code>, it is set to
     * {
@link javax.xml.XMLConstants#NULL_NS_URI
     * XMLConstants.NULL_NS_URI}.  This value represents no
     * explicitly defined Namespace as defined by the <a
     * href="
http://www.w3.org/TR/REC-xml-names/#ns-qualnames">Namespaces
     * in XML</a> specification.  This action preserves compatible
     * behavior with QName 1.0.  Explicitly providing the {
@link
     * javax.xml.XMLConstants#NULL_NS_URI
     * XMLConstants.NULL_NS_URI} value is the preferred coding
     * style.</p>
     *
     * <p>If the local part is <code>null</code> an
     * <code>IllegalArgumentException</code> is thrown.
     * A local part of "" is allowed to preserve
     * compatible behavior with QName 1.0. </p>
     *
     * <p>When using this constructor, the prefix is set to {
@link
     * javax.xml.XMLConstants#DEFAULT_NS_PREFIX
     * XMLConstants.DEFAULT_NS_PREFIX}.</p>
     *
     * <p>The Namespace URI is not validated as a
     * <a href="
http://www.ietf.org/rfc/rfc2396.txt">URI reference</a>.
     * The local part is not validated as a
     * <a href="
http://www.w3.org/TR/REC-xml-names/#NT-NCName">NCName</a>
     * as specified in <a href="
http://www.w3.org/TR/REC-xml-names/">Namespaces
     * in XML</a>.</p>
     *
     * 
@param namespaceURI Namespace URI of the <code>QName</code>
     * 
@param localPart    local part of the <code>QName</code>
     *
     * 
@throws IllegalArgumentException When <code>localPart</code> is
     *   <code>null</code>
     *
     * 
@see #QName(String namespaceURI, String localPart, String
     * prefix) QName(String namespaceURI, String localPart, String
     * prefix)
     
*/
    
public QName(final String namespaceURI, final String localPart) {
        
this(namespaceURI, localPart, XMLConstants.DEFAULT_NS_PREFIX);
    }

从上面的解释中可以看出,QName的Constructor第一个参数是XML的namespace,第二个参数是该namepace下的一个名字。所以对于客户端的代码而言,QName qname=new QName("SparePartDetails","SparePartBean");所定义的这两个参数第一个是SparetDetails是namespace,第二个SparePartBean是JavaBean转成XML,在XML中的名字。这个问题在Web Service中的WSDL中得到了验证。

2. WSDL代码
通过地址:http://localhost:8080/ws/services/SparePartService?wsdl ,即可看到。其中在wsdl:types节点的信息如下:

 <wsdl:types>
  
<schema targetNamespace="SparePartDetails" xmlns="http://www.w3.org/2001/XMLSchema">
   
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   
<complexType name="SparePartBean">
    
<sequence>
     
<element name="description" nillable="true" type="soapenc:string"/>
     
<element name="price" type="xsd:float"/>
     
<element name="sku" nillable="true" type="soapenc:string"/>
    
</sequence>
   
</complexType>
  
</schema>
 
</wsdl:types>

其中详细描述了SparePartDetails namespace下面存在一个因为SpartPartBean的XML 数据类型。这里详细描述了当JavaBean转成XML的时候,XML的数据结构。

结论:
     位于AXIS Service的WSDD中的beanMapping规定了Service JavaBean转成XML的时候,XML代码所必须的的namespace和名字。当客户端接到SOAP XML代码时,必须使用那个namespace和名字才能将相应的XML代码转成JavaBean。所以客户端的代码的确只是和SOAP XML相关。

只有注册用户登录后才能发表评论。


网站导航: