WebService服務端與客戶端開發

最近客戶提出了將我們做的系統接入到他們系統之中,方便他們進行集中管理這個需求,其中主要就是運用了WebService技術來進行系統之間的接入。在此記錄一下整個WebService是如何嵌入我們系統的以及具體的開發流程。

服務端開發

添加jar包
我是使用axis2來輔助生成WebService服務端,因此需要添加相應的插件。
首先官網下載axis2-1.6.3,解壓到文件夾中,並添加到eclipse中,window->preferences下:

具體位置

服務端的生成
首先建立服務端包以及需要的服務類,類建好之後右鍵該類,選擇Web Services->create web service.出現如下對話框:

直接點擊完成按鈕即可生成相應的服務端。
項目結構:

服務端檢測
生成服務端之後,運行web項目,在瀏覽器上訪問http://localhost:8080/com.primeton.testws/services/UpdateAppAcctAuthorServices?wsdl , 出現如下頁面即爲成功:

發佈成功後,客戶端即可根據wsdl上的信息進行遠程訪問。

修改wsdl中的信息
爲什麼要修改wsdl中的信息呢?
1.因爲有時候我們不想暴露有關自己項目的太多信息,例如:項目名稱、類名、方法名以及項目的命名空間。這時就要修改相關的配置文件來改變wsdl中的相關信息,達到隱藏的作用。
2.一般客戶端與服務端是2個不同的公司做的,若對方公司有要求,則必須改爲要求的命名,不然訪問不同。(PS:我們當時就是被坑了)
需要修改的文件爲:server-config.wsdd
修改項爲:

 <ns1:service name="UpdateAppAcctAuthorServices" provider="java:RPC" style="wrapped" use="literal">
  <ns1:operation name="updateAppAcctAuthor" qname="ns2:UpdateAppAcctAuthorServices" returnQName="ns2:UpdateAppAcctAuthorServicesReturn" returnType="xsd:string" soapAction="" xmlns:ns2="http://www.primeton.com/web" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <ns1:parameter qname="ns2:RequestInfo" type="xsd:string"/>
  </ns1:operation>
  <ns1:parameter name="allowedMethods" value="updateAppAcctAuthor"/>
  <ns1:parameter name="wsdlPortType" value="UpdateAppAcctAuthorServices"/>
  <ns1:parameter name="typeMappingVersion" value="1.2"/>
  <ns1:parameter name="schemaQualified" value="http://www.primeton.com/web"/>
  <ns1:parameter name="wsdlServicePort" value="UpdateAppAcctAuthorServices"/>
  <ns1:parameter name="className" value="webserver.UpdateAppAcctAuthorServices"/>
  <ns1:parameter name="wsdlTargetNamespace" value="http://www.primeton.com/web"/>
  <ns1:parameter name="wsdlServiceElement" value="UpdateAppAcctAuthorServicesService"/>
 </ns1:service>

1.修改qname來改變wsdl中顯示的方法名
2.修改returnQName來改名wsdl中顯示的返回名
3.修改ns1:parameter qname=”ns2:RequestInfo”來改變方法中的參數名。
4.修改 ns1:parameter name=”wsdlTargetNamespace”value=”http://www.primeton.com/web”來改變命名空間。
5.修改後就可以讓客戶端按照修改後的命名來進行訪問了。


客戶端開發

客戶端開發即爲調用別人所寫的web服務。
所需要的jar包:

import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

除了引入的這些jar包之外,還需要axis2 下的commons-httpclient-3.1.jar包,通過該包進行webservice通信。

調用方式也有好幾種,我這裏介紹的是RPC遠程調用的方法。具體調用代碼及註釋如下:

        String requestInfo = createRequestInfo2();

        String serviceUrl = "http://localhost:8080/com.primeton.testws/services/UpdateAppAcctSoap?wsdl";

        RPCServiceClient serviceClient = null;
        String resultString = "";
        try {
            serviceClient = new RPCServiceClient();
        } catch (AxisFault e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        Options options = serviceClient.getOptions();
        EndpointReference targetEPR = new EndpointReference(serviceUrl);
        options.setTo(targetEPR);
        // 服務器端開放的方法名

        String wsFunction = "UpdateAppAcctSoap";

        // 要傳給服務器開放方法的參數.
        String xmlStr = requestInfo ;

        /*在創建QName對象時,QName類的構造方法的第一個參數表示WSDL文件的命名空間名,
        也就是<wsdl:definitions>元素的targetNamespace屬性值*/
        QName qName = new QName("http://www.primeton.com/web", wsFunction);
        // 參數,如果有多個,繼續往後面增加即可,不用指定參數的名稱
        Object[] inputArgs = new Object[] {  };
        if(xmlStr != null && !"".equals(xmlStr)){
            inputArgs = new Object[] { xmlStr };
        }
        /*
        返回參數類型,這個和axis1有點區別
        invokeBlocking方法有三個參數,其中第一個參數的類型是QName對象,表示要調用的方法名;
                第二個參數表示要調用的WebService方法的參數值,參數類型爲Object[];
                第三個參數表示WebService方法的返回值類型的Class對象,參數類型爲Class[]。
                當方法沒有參數時,invokeBlocking方法的第二個參數值不能是null,而要使用new Object[]{}
                如果被調用的WebService方法沒有返回值,應使用RPCServiceClient類的invokeRobust方法,
                該方法只有兩個參數,它們的含義與invokeBlocking方法的前兩個參數的含義相同
        */
        Class[] returnTypes = new Class[] { String.class };
        Object[] response;
        try {
            response = serviceClient.invokeBlocking(qName, inputArgs, returnTypes);
            resultString = (String) response[0];
            System.out.println(resultString);
        } catch (AxisFault e) {
            e.printStackTrace();
        }

    }

requestInfo 是客戶端發送的請求報文:

<?xml version="1.0" encoding="UTF-8"?>

<USERMODIFYREQ>
  <HEAD>
    <CODE></CODE>
    <SID></SID>
    <TIMESTAMP></TIMESTAMP>
    <SERVICEID></SERVICEID>
  </HEAD>
  <BODY>
    <OPERATORID>sysadmin</OPERATORID>
    <OPERATORPWD></OPERATORPWD>
    <OPERATORIP></OPERATORIP>
    <MODIFYMODE>add</MODIFYMODE>
    <USERINFO>
      <USERID>111111</USERID>
      <LOGINNO>111111</LOGINNO>
      <USERNAME></USERNAME>
      <ORGID></ORGID>
      <EMAIL>[email protected]</EMAIL>
      <MOBILE>11111111111</MOBILE>
      <PASSWORD>111111</PASSWORD>
      <STATUS></STATUS>
      <EFFECTDATE></EFFECTDATE>
      <EXPIREDATE></EXPIREDATE>
      <REMARK></REMARK>
    </USERINFO>
  </BODY>
</USERMODIFYREQ>

運行客戶端,服務端返回的報文如下:

<?xml version="1.0" encoding="UTF-8"?>

<USERMODIFYRSP>
  <HEAD>
    <CODE></CODE>
    <SID></SID>
    <TIMESTAMP></TIMESTAMP>
    <SERVICEID>SHNGDM</SERVICEID>
  </HEAD>
  <BODY>
    <MODIFYMODE>add</MODIFYMODE>
    <USERID>111111</USERID>
    <LOGINNO>111111</LOGINNO>
    <RSP>0</RSP>
    <ERRDESC></ERRDESC>
  </BODY>
</USERMODIFYRSP>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章