上篇文章看完之後,感覺很清晰了,於是我下載了sapjco3,準備自己親自寫一遍,可是,等我下載下來準備開寫的時候,
發現了我在JCO中並沒有發現createClient()等方法,查閱了很多文章後發現,貌似sapjco3和以前的寫法不太一樣。於是,
在這裏,我將sapjco3的用法展示出來,都做了詳細的解釋。
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
public class ConnectNoPool {// 直連方式,非連接池
// 連接屬性配置文件名,名稱可以隨便取
static String ABAP_AS = "ABAP_AS_WITHOUT_POOL";
static {
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST,
"192.168.111.137");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");
connectProperties
.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties.setProperty(DestinationDataProvider.JCO_USER,
"SAPECC");
// 注:密碼是區分大小寫的,要注意大小寫
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,
"sapecc60");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
// 需要將屬性配置保存屬性文件,該文件的文件名爲 ABAP_AS_WITHOUT_POOL.jcoDestination,
// JCoDestinationManager.getDestination()調用時會需要該連接配置文件,後綴名需要爲jcoDestination
createDataFile(ABAP_AS, "jcoDestination", connectProperties);
}
// 基於上面設定的屬性生成連接配置文件
static void createDataFile(String name, String suffix, Properties properties) {
File cfg = new File(name + "." + suffix);
if (!cfg.exists()) {
try {
FileOutputStream fos = new FileOutputStream(cfg, false);
properties.store(fos, "for tests only !");
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void connectWithoutPool() throws JCoException {
// 到當前類所在目錄中搜索 ABAP_AS_WITHOUT_POOL.jcoDestination
// 屬性連接配置文件,並根據文件中的配置信息來創建連接
JCoDestination destination = JCoDestinationManager
.getDestination(ABAP_AS);// 只需指定文件名(不能帶擴展名jcoDestination名,會自動加上)
System.out.println("Attributes:");
// 調用destination屬性時就會發起連接,一直等待遠程響應
System.out.println(destination.getAttributes());
}
public static void main(String[] args) throws JCoException {
connectWithoutPool();
}
}
連接池
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
public class ConnectPooled {// 連接池
static String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
static {
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST,
"192.168.111.137");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");
connectProperties
.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties.setProperty(DestinationDataProvider.JCO_USER,
"SAPECC");
// 注:密碼是區分大小寫的,要注意大小寫
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,
"sapecc60");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
// *********連接池方式與直接不同的是設置了下面兩個連接屬性
// JCO_PEAK_LIMIT - 同時可創建的最大活動連接數,0表示無限制,默認爲JCO_POOL_CAPACITY的值
// 如果小於JCO_POOL_CAPACITY的值,則自動設置爲該值,在沒有設置JCO_POOL_CAPACITY的情況下爲0
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,
"10");
// JCO_POOL_CAPACITY - 空閒連接數,如果爲0,則沒有連接池效果,默認爲1
connectProperties.setProperty(
DestinationDataProvider.JCO_POOL_CAPACITY, "3");
createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
}
static void createDataFile(String name, String suffix, Properties properties) {
File cfg = new File(name + "." + suffix);
if (!cfg.exists()) {
try {
FileOutputStream fos = new FileOutputStream(cfg, false);
properties.store(fos, "for tests only !");
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void connectWithPooled() throws JCoException {
JCoDestination destination = JCoDestinationManager
.getDestination(ABAP_AS_POOLED);
System.out.println("Attributes:");
System.out.println(destination.getAttributes());
}
public static void main(String[] args) throws JCoException {
connectWithPooled();
}
}
DestinationDataProvider接口(不需連接屬性配置文件)
上面直接連接、連接池,兩種連接方法都需要先建立一個屬性配置文件,然後JCo再從建立好文件裏讀取連接到SAP服務器所需要的連接屬性,這個方法很難在實際的環境中應用,存儲SAP連接屬性配置信息到一個文件裏,是比較不安全的。然而,JCO爲我們提供了另外一種連接的方法:DestinationDataProvider,通過它我們就可以將一個連接變量信息存放在內存裏
import java.util.HashMap;
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
importcom.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.Environment;
public class CustomSAPDestinationDataProvider {
static class MyDestinationDataProvider implements DestinationDataProvider {
privateDestinationDataEventListenereL;
private HashMap<String, Properties>destinations;
private static MyDestinationDataProvider provider = new MyDestinationDataProvider();
private MyDestinationDataProvider() {// 單例模式
if (provider == null) {
destinations = new HashMap<String, Properties>();
}
}
public static MyDestinationDataProvider getInstance() {
return provider;
}
// 實現接口:獲取連接配置屬性
public Properties getDestinationProperties(String destinationName) {
if (destinations.containsKey(destinationName)) {
return destinations.get(destinationName);
} else {
throw new RuntimeException("Destination " + destinationName
+ " is not available");
}
}
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eL = eventListener;
}
public boolean supportsEvents() {
return true;
}
/**
* Add new destination 添加連接配置屬性
*
* @param properties
* holds all the required data for a destination
**/
void addDestination(String destinationName, Properties properties) {
synchronized (destinations) {
destinations.put(destinationName, properties);
}
}
}
public static void main(String[] args) throws Exception {
// 獲取單例
MyDestinationDataProvider myProvider = MyDestinationDataProvider
.getInstance();
// Register the MyDestinationDataProvider 環境註冊
Environment.registerDestinationDataProvider(myProvider);
// TEST 01:直接測試
// ABAP_AS is the test destination name :ABAP_AS爲目標連接屬性名(只是邏輯上的命名)
String destinationName = "ABAP_AS";
System.out.println("Test destination - " + destinationName);
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST,
"192.168.111.123");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");
connectProperties
.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties.setProperty(DestinationDataProvider.JCO_USER,
"SAPECC");
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,
"sapecc60");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
// Add a destination
myProvider.addDestination(destinationName, connectProperties);
// Get a destination with the name of "ABAP_AS"
JCoDestination DES_ABAP_AS = JCoDestinationManager
.getDestination(destinationName);
// Test the destination with the name of "ABAP_AS"
try {
DES_ABAP_AS.ping();
System.out.println("Destination - " + destinationName + " is ok");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Destination - " + destinationName
+ " is invalid");
}
// TEST 02:連接池測試
// Add another destination to test
// ABAP_AS2 is the test destination name
String destinationName2 = "ABAP_AS2";
System.out.println("Test destination - " + destinationName2);
Properties connectProperties2 = new Properties();
connectProperties2.setProperty(DestinationDataProvider.JCO_ASHOST,
"192.168.111.123");
connectProperties2.setProperty(DestinationDataProvider.JCO_SYSNR, "00");
connectProperties2
.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties2.setProperty(DestinationDataProvider.JCO_USER,
"SAPECC");
connectProperties2.setProperty(DestinationDataProvider.JCO_PASSWD,
"sapecc60");
connectProperties2.setProperty(DestinationDataProvider.JCO_LANG, "en");
connectProperties2.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,
"10");
connectProperties2.setProperty(
DestinationDataProvider.JCO_POOL_CAPACITY, "3");
// Add a destination
myProvider.addDestination(destinationName2, connectProperties2);
// Get a destination with the name of "ABAP_AS2"
JCoDestination DES_ABAP_AS2 = JCoDestinationManager
.getDestination(destinationName2);
// Test the destination with the name of "ABAP_AS2"
try {
DES_ABAP_AS2.ping();
System.out.println("Destination - " + destinationName2 + " is ok");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Destination - " + destinationName2
+ " is invalid");
}
}
}
訪問結構 (Structure)
public static void accessSAPStructure() throws JCoException {
JCoDestination destination = JCoDestinationManager
.getDestination(ABAP_AS);
JCoFunction function = destination.getRepository().getFunction(
"RFC_SYSTEM_INFO");//從對象倉庫中獲取 RFM 函數
if (function == null)
throw new RuntimeException(
"RFC_SYSTEM_INFO not found in SAP.");
try {
function.execute(destination);
} catch (AbapException e) {
System.out.println(e.toString());
return ;
}
JCoStructure exportStructure = function.getExportParameterList()
.getStructure("RFCSI_EXPORT");
System.out.println("System info for "
+ destination.getAttributes().getSystemID() + ":\n");
for (int i = 0; i < exportStructure.getMetaData().getFieldCount(); i++) {
System.out.println(exportStructure.getMetaData().getName(i) + ":\t"
+ exportStructure.getString(i));
}
System.out.println();
// JCo still supports the JCoFields, but direct access via getXX is more
// efficient as field iterator 也可以使用下面的方式來遍歷
System.out.println("The same using field iterator: \nSystem info for "
+ destination.getAttributes().getSystemID() + ":\n");
for (JCoField field : exportStructure) {
System.out.println(field.getName() + ":\t" + field.getString());
}
System.out.println();
//*********也可直接通過結構中的字段名或字段所在的索引位置來讀取某個字段的值
System.out.println("RFCPROTO:\t"+exportStructure.getString(0));
System.out.println("RFCPROTO:\t"+exportStructure.getString("RFCPROTO"));
}
public static void main(String[] args) throws JCoException {
accessSAPStructure();
}
訪問表 (Table)
public static void workWithTable() throws JCoException {
JCoDestination destination = JCoDestinationManager
.getDestination(ABAP_AS);
JCoFunction function = destination.getRepository().getFunction(
"BAPI_COMPANYCODE_GETLIST");//從對象倉庫中獲取 RFM 函數:獲取公司列表
if (function == null)
throw new RuntimeException(
"BAPI_COMPANYCODE_GETLIST not found in SAP.");
try {
function.execute(destination);
} catch (AbapException e) {
System.out.println(e.toString());
return ;
}
JCoStructure return Structure = function.getExportParameterList()
.getStructure("return ");
//判斷讀取是否成功
if (!(return Structure.getString("TYPE").equals("") || return Structure
.getString("TYPE").equals("S"))) {
throw new RuntimeException(return Structure.getString("MESSAGE"));
}
//獲取Table參數:COMPANYCODE_LIST
JCoTable codes = function.getTableParameterList().getTable(
"COMPANYCODE_LIST");
for (int i = 0; i < codes.getNumRows(); i++) {//遍歷Table
codes.setRow(i);//將行指針指向特定的索引行
System.out.println(codes.getString("COMP_CODE") + '\t'
+ codes.getString("COMP_NAME"));
}
// move the table cursor to first row
codes.firstRow();//從首行開始重新遍歷 codes.nextRow():如果有下一行,下移一行並返回True
for (int i = 0; i < codes.getNumRows(); i++, codes.nextRow()) {
//進一步獲取公司詳細信息
function = destination.getRepository().getFunction(
"BAPI_COMPANYCODE_GETDETAIL");
if (function == null)
throw new RuntimeException(
"BAPI_COMPANYCODE_GETDETAIL not found in SAP.");
function.getImportParameterList().setValue("COMPANYCODEID",
codes.getString("COMP_CODE"));
// We do not need the addresses, so set the corresponding parameter
// to inactive.
// Inactive parameters will be either not generated or at least
// converted. 不需要返回COMPANYCODE_ADDRESS參數(但服務器端應該還是組織了此數據,只是未經過網絡傳送?)
function.getExportParameterList().setActive("COMPANYCODE_ADDRESS",
false);
try {
function.execute(destination);
} catch (AbapException e) {
System.out.println(e.toString());
return ;
}
return Structure = function.getExportParameterList().getStructure(
"return ");
if (!(return Structure.getString("TYPE").equals("")
|| return Structure.getString("TYPE").equals("S") || return Structure
.getString("TYPE").equals("W"))) {
throw new RuntimeException(return Structure.getString("MESSAGE"));
}
JCoStructure detail = function.getExportParameterList()
.getStructure("COMPANYCODE_DETAIL");
System.out.println(detail.getString("COMP_CODE") + '\t'
+ detail.getString("COUNTRY") + '\t'
+ detail.getString("CITY"));
}// for
}
附上sapjco3的下載地址:http://download.csdn.net/detail/qq_30698633/9912603