java 通過Axis調用Webservice

String endpointURL = "http://localhost:8080/ws/services/SparePartService";
String methodName = "getSparepart";

Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpointURL));
call.setOperationName(new QName("SparePartService", methodName));

call.addParameter("sku", XMLType.XSD_STRING, ParameterMode.IN);

QName qname = new QName("SparePartDetails", "SparePartBean");
Class cls = org.bluebear.ws.advanced.customdatatype.SparePartBean.class;
call.registerTypeMapping(cls, qname, BeanSerializerFactory.class, BeanDeserializerFactory.class);
call.setReturnType(qname);

Object[] params = new Object[] { "222222" };
SparePartBean spBean = (SparePartBean) call.invoke(params);

System.out.println(spBean);

需要引入的jar包:

axis.jar
jaxrpc.jar
commons-discovery-0.2.jar
wsdl4j-1.5.1.jar
saaj.jar


注意事項:

(1) 即使方法返回爲void,也需要設置returntype, 可以設置returnType爲String

(2) 如果是通過https的連接方式訪問,需要在最開始加下面的參數設置

    System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");    

否則會報下面的錯誤:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

也可以通過這個方法解決:http://blog.csdn.net/jadyer/article/details/7799540

 

有一位同仁針對下面的一段AXIS客戶端代碼提出了這樣的問題:QName qname=new QName("SparePartDetails","SparePartBean");這2個參數是什麼意義?
只是需要知道如何將返回的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相關。

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章