最近客戶提出了將我們做的系統接入到他們系統之中,方便他們進行集中管理這個需求,其中主要就是運用了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>