ASE自從12.5.1以後提供了WebService的功能。ASE提供的WebService
功能總結下來包括三個部分:
•ASE提供WebService的服務端,供其它WebService客戶端調用。這也叫做ASE WebService生産者。ASE WebService生産者提供了三個方法,供客戶端調用,將SQL或者存儲過程執行結果以SOAP格式返回給調用者。
•ASE WebService組件也可以作爲WebService的客戶端,調用其他WebService的服務。這也叫做ASE WebService消費者。
•用戶也可以在ASE WebService服務器上自定義自己的WebService服務,供其他客戶端掉用。用戶自定義WebService服務可以執行一段SQL語句並返回執行結果。
本文以ASE15.0.2爲例介紹一下如何配置ASE WebService生産者供其它客戶端調用。
安裝ASE WebService組件
在安裝ASE服務器時,需要安裝ASE WebService組件。這一組件是ASE的一個Feature,需要有ASE WebService的License才能使用這一功能。
安裝過程如果選擇ASE WebService組件,則安裝時就可以配置ASE WebService服務器。配置過程也可以放到安裝結束以後通過Sybase Central單獨配置。
ASE WebService組件的配置
ASE WebService組件的配置包括三部分內容:生産者配置、SSL配置、消費者配置。
配置過程非常的簡單,如果是通過Sybase Central配置,只需根據提示進行配置即可。如果想通過WebService來執行SQL語句或者ASE中的存儲過程,只需要配置生産者即可,SSL與消費者的配置可跳過。此時只需要指定WebService服務器供客戶端掉用的端口號。默認端口號是8181。
激活ASE WebService功能
配置完成後,首先使用sa登錄到ASE數據庫:
Isql –U sa –P –SDBNAME
執行如下語句激活WebService功能:
Sp_configure “enable webservices”,1
Go
如果沒有webservice 功能的license,將不能激活該功能。
ASE WebService服務器的啓動
使用命令行方式進入到C:\Sybase\WS-15_0\bin下(c:\sybase是ASE的安裝目錄)執行:
runws -U sa -P nopasswordspecified -S DBNAME
注意,此處如果sa口令爲空,-P 後的參數一定要爲nopasswordspecified 。-S 後面跟的是ASE服務器的名字,一定要與c:\sybase\ini\sql.ini裏配置的服務名稱相符。
如果一切正常,那麽ASE WebService將爲啓動,端口號8181。此時如果在IE浏覽器裏輸入:http://localhost:8181/services/ase?wsdl,將會出現ase服務的WSDL文件。ase服務提供了三個方法:
•Login:建立一個持久的數據庫連接。但這個不是必需的,如果直接調用execute方法,系統會使用execute方法提供的用戶名與口令建立一個臨時的數據庫連接。
•Logout:斷開由Login建立的持久連接
•Execute:執行SQL或者存儲過程。關于該方法的參數請參考Sybase官方文檔。
Runws還有其他參數,詳細請參考sybase官方文檔。
停止ASE WebService的命令如下:
stopws -U sa -P nopasswordspecified -S DBNAME
測試:
有了WSDL,想必大家都應該知道下一步如何做了。只需要使用工具將WSDL編譯成後面我們需要的客戶端stub文件即可。
如果你需要立即測試ASE WebService配置是否正確,ASE提供了一個測試用的客戶端。在命令行下進入到C:\Sybase\WS-15_0\samples\apacheclient,執行:
runexecute "http://localhost:8181/services/ase" DBNAME sa "" "columnstyle=attribute,tablename=ws" all 1 "select @@version"
這個測試腳本通過java調用ASE WebService發布的ase服務的execute方法,用以執行SQL: select @@version。如果一切正常,你將會看到你非常熟悉的xml輸出。
Runexecute的語法如下:
runexecute “web_service_URL” aseServerName user_ID password “SQLX_option” output_class count “sql_statement”
參數如下:
• web_service_URL
正在使用的Web 服務的位置。
• aseServerName
SOAP string,表示interfaces 文件或LDAP 服務器中Adaptive ServerEnterprise 服務器的名稱。
• user_ID
登錄到Adaptive Server Enterprise 所需的用戶ID。
• password
登錄到Adaptive Server Enterprise 所需的口令。
• SQLX_option
表示一個或多個option 參數的字符串。這些參數用于指定SQLX 結果集的特性。以下是有效的選項參數:
• binary={hex | base64}
• columnstyle={element | attribute}
• format={yes | no}
• header={yes | no}
• nullstyle={attribute | omit}
• prefix=“value”
• root={yes | no}
• rowname=“value”
• schemaloc=“value”
• statement={yes | no}
• tablename=“value”
• targetns=“value”
• output_class
所需的輸出類型。以下是此參數的有效值:
• schema — 返回
XML 模式。
• dtd — 返回
XML DTD。
• data — 返回結果集。
• all — 返回模式、DTD 和數據。
• count
執行此語句的次數。如果count 的值大于
1,則會創建一個會話並使用持久連接。
• sql_statement
要在Adaptive Server Enterprise 上執行的語句。該語句必須用雙引號分隔。
你可以試著改變一下runexecute的參數看一下輸出的變化:
runexecute "http://localhost:8181/services/ase" DBNAME sa "" "columnstyle=attrib ute,tablename=ws" all 1 "select @@version"
當然,你也可以改變執行的SQL語句,看看執行結果輸出。
Runexecute調用的java類的源代碼請參考本文的最後一部分。這個源代碼可以作爲一個示例程序,供參考。
其他的配置工作
對于將ASE作爲其他WebService的客戶端的配置(使用sp_webservices),以及如何配置自定義的WebService服務(使用create service,drop service命令),ASE都提供了相應的命令,也非常的簡單易用,另外還有SSL的配置。大家不妨參考Sybase文檔逐一驗證。
客戶端參考代碼
import com.sybase.apachetest.*;
import javax.xml.rpc.Stub;
import java.net.URL;
import java.security.Security;
public class ASEExecute
{
public static void main(String[] args)
{
try
{
if (args.length <
{
System.out.println ("Gotta have 8 args only got: " + args.length + "\n";
System.out.println ("Argument 1: Endpoint for SOAP ";
System.out.println ("Argument 2: ASE Service Name ";
System.out.println ("Argument 3: ASE Username to login as ";
System.out.println ("Arugment 4: ASE Password to use in login ";
System.out.println ("Argument 5: SQL X Options ";
System.out.println ("Argument 6: Dataoutput (one of all, schema, dtd or data or count)";
System.out.println ("Arugment 7: Number of times to execute (in session) ";
System.out.println ("Arugment 8: SQL to execute ";
System.exit (1);
}
String endpoint = args[0];
System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol";
Security.addProvider (new com.sun.net.ssl.internal.ssl.Provider());
URL endURL = new URL (endpoint);
String serverName = args[1];
String userName = args[2];
String password = args [3];
if (password.compareTo("nopasswordspecified") == 0)
{
System.out.println ("Replacing password with null token.");
password = "";
}
String sqlxOptions = args[4];
String dataOutput = args[5];
String numExecutionStr = args[6];
int numExecution = 1;
try
{
Integer tmp = new Integer (numExecutionStr);
numExecution = tmp.intValue ();
}
catch (NumberFormatException err)
{
System.out.println ("Could not convert " + numExecutionStr + " to a number.");
System.out.println ("Assuming 1 execution.");
numExecution = 1;
}
String sql = args[7];
System.out.println ("SOAP Endpoint: " + endpoint);
System.out.println ("ASE Service Name: " + serverName);
System.out.println ("ASE Username: " + userName);
System.out.println ("ASE Password: ********** " );
System.out.println ("SQL X options: " + sqlxOptions);
System.out.println ("Data Output: " + dataOutput);
System.out.println ("Number of executions: " + numExecution);
System.out.println ("Sql Select to execute: " + sql);
ExecuteStoredProcServiceLocator service = new ExecuteStoredProcServiceLocator ();
if (numExecution != 1)
{
service.setMaintainSession (true);
}
ExecuteStoredProc port = service.getase(endURL);
for (int ii = 0; ii < numExecution; ii++)
{
DataReturn[] data = port.execute (serverName,
userName,
password,
sqlxOptions,
sql);
if (data != null)
{
for (int jj = 0; jj < data.length; jj++)
{
System.out.println ("rinting result set #" + jj );
if (dataOutput.compareTo ("all") == 0
|| dataOutput.compareTo ("dtd") == 0)
{
System.out.println ("data.getDTD is: \n" + data[jj].getDTD ());
}
if (dataOutput.compareTo ("all") == 0
|| dataOutput.compareTo ("data") == 0)
{
System.out.println ("data.getXML is: \n" + data[jj].getXML ());
}
if (dataOutput.compareTo ("all") == 0
|| dataOutput.compareTo ("schema") == 0)
{
System.out.println ("data.getSchema is: \n" + data[jj].getSchema ());
}
System.out.println ("data.updateCount is: " + data[jj].getUpdateCount ());
}
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}