上篇文章看完之后,感觉很清晰了,于是我下载了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