WebService服務端與客戶端開發
最近客戶提出了將我們做的系統接入到他們系統之中,方便他們進行集中管理這個需求,其中主要就是運用了WebService技術來進行系統之間的接入。在此記錄一下整個WebService是如何嵌入我們系統的以及具體的開發流程。
服務端開發
新增jar包
我是使用axis2來輔助生成WebService服務端,因此需要新增相應的外掛。
首先官網下載axis2-1.6.3,解壓到資料夾中,並新增到eclipse中,window->preferences下:
服務端的生成
首先建立服務端包以及需要的服務類,類建好之後右鍵該類,選擇Web Services->create web service.出現如下對話方塊:
直接點選完成按鈕即可生成相應的服務端。
專案結構:
釋出成功後,客戶端即可根據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>