SAP JCO connector3与SAP 通过RFC的方式建立连接以及数据交互的例子。
步骤:
- 初始化连接用户名,密码,连接池等信息
sap-conig.properties文件:
#notes:更多配置项@see com.sap.conn.jco.ext.DestinationDataProvider
#客户端编号
jco.client.client=830
#用户名
jco.client.user=
#密码
jco.client.passwd=
#语言
jco.client.lang=ZH
#IP
jco.client.ashost=
#系统编号
jco.client.sysnr=10
#最大空闲连接数
jco.destination.pool_capacity=1000
#超时
jco.destination.max_get_client_time=100
#最大活动连接数
jco.destination.peak_limit=1000
SapJcoStore.java 初始化
/**
* 初始化SAP连接
* @param fdPoolName
* @return
* @throws Exception
*/
private static synchronized JCoDestination doInitialize(String fdPoolName)
throws Exception {
Properties sapConfig=new Properties();
// Properties的配置项@see com.sap.conn.jco.ext.DestinationDataProvider
InputStream is=SapJcoStore.class.getResourceAsStream("/com/test/share/sap/sap-config.properties");
sapConfig.load(is);
// 扩展参数,需要扩展参数的时候使用
sapConfig.setProperty((String)DestinationDataProvider.class.getField("JCO_SAPROUTER").get(DestinationDataProvider.class),"/H/219.141.250.71/H/");
createDataFile(fdPoolName, "jcoDestination", sapConfig);
JCoDestination destination=getDestination(fdPoolName);
return destination;
}
/**
* 创建连接文件(必须)
* @param name
* @param suffix
* @param properties
*/
private static void createDataFile(String name, String suffix, Properties properties) {
File cfg = new File(name + "." + suffix);
try {
FileOutputStream fos = new FileOutputStream(cfg, false);
properties.store(fos, "for connection");
fos.close();
} catch (Exception e) {
throw new RuntimeException("Unable to create the destination file "
+ cfg.getName(), e);
}
}
- 建立连接池
public static Hashtable<String, JCoDestination> destinations = new Hashtable<String, JCoDestination>();
/**
* 获取连接池,利用JCoDestinationManager创建连接池放到表中
*
* @param fdPoolName
* @return
* @throws Exception
*/
public static JCoDestination getDestination(String fdPoolName) throws Exception {
JCoDestination destination = null;
if (destinations.containsKey(fdPoolName)) {
destination = destinations.get(fdPoolName);
} else {
destination = JCoDestinationManager.getDestination(fdPoolName);
destinations.put(fdPoolName, destination);
}
return destination;
}
- 通过连接池获取BAPI传输对象JCOFunction
/**
* 根据连接池,rfc 名称获取rfc函数模板
*
* @param rfcName
* @param poolName
* @return
* @throws Exception
*/
public static JCoFunctionTemplate getRfcTemplate(String rfcName,
String fdPoolName) throws Exception {
JCoDestination destination = SapJcoStore.getDestination(fdPoolName);
JCoRepository repository = null;
try {
repository = destination.getRepository();
} catch (Exception e) {
destination = JCoDestinationManager.getDestination(fdPoolName);
SapJcoStore.destinations.remove(fdPoolName);
SapJcoStore.destinations.put(fdPoolName, destination);
repository = destination.getRepository();
}
JCoFunctionTemplate template = repository.getFunctionTemplate(rfcName);
return template;
}
/**
* 根据RFC 函数名称,连接池获取函数
* @param rfcName
* @param fdPoolName
* @param store
* @return
* @throws Exception
*/
public static JCoFunction getRfcFunction(String rfcName, String fdPoolName) throws Exception {
JCoFunctionTemplate template = getRfcTemplate(rfcName, fdPoolName);
return template.getFunction();
}
- 填充数据-->execute
填充数据有import 跟table 2种
/**
* 填充数据,根据上面表格
* 在SAP中间件其实也就是解析在填充数据这里加工很多配置,实现同理
*
*/
public static JCoFunction fillData(JCoFunction jcoFunc){
JCoRecord record =jcoFunc.getImportParameterList();
// 构造业务数据
Map<String, Object> importData=new HashMap<String, Object>();
importData.put("COMPANYCODE", "8880");
importData.put("CUSTOMER", "0099000032");
importData.put("KEYDATE", "20070830");
// 填充传入值
for(String key:importData.keySet()){
Object value=importData.get(key);
record.setValue(key, value);
}
// 上面构造数据只有传入的参数数据,下面是传入table的数据
/*设置值
JCoTable jcoTable= jcoFunc.getTableParameterList().getTable("");
for(){
// 增加一行数据,同时游标也只想了当前行
jcoTable.appendRow();
// 设置当前行的某个列的值
jcoTable.setValue("", "");
jcoTable.setValue("", "");
....
}
*/
return jcoFunc;
}
execute
/**
*
* @param poolName 连接池名称
* @param function 传输的带数据JCoFunction对象
* @return
* @throws Exception
*/
public Object processSap(String poolName, JCoFunction function)
throws Exception {
doBefore();
try {
parsePostData(function);
JCoFunction func = execFunc(function, poolName);
Object rtn = parseRtnData(func);
return rtn;
} catch (Exception e) {
doError(e);
} finally {
doAfter();
}
return null;
}
- 处理返回值 主要是遍历,游标的处理
/**
*
* @param jcoFunction
* @param tableName
*/
public static void resultPrint(JCoFunction jcoFunction,String tableName){
// 需要打印的列名称
List<String> printKey=new ArrayList<String>();
printKey.add("COMP_CODE");
printKey.add("CUSTOMER");
printKey.add("SP_GL_IND");
printKey.add("ITEM_TEXT");
// 得到table
JCoTable table =jcoFunction.getTableParameterList().getTable(tableName);
// 取得行
int rows=table.getNumRows();
for(int i=0,len=rows;i<len;i++){
// 游标移动到row
table.setRow(i);
JCoFieldIterator iterator = table.getFieldIterator();
while (iterator.hasNextField()) {
// System.out.println(parameterField.getName()+"JCoFieldIterator");
JCoField recordField = iterator.nextField();
String fieldName=recordField.getName();
// 过滤不需要的字段
if(!printKey.contains(fieldName))
{
continue;
}
// 取值打印
// Object value=recordField.getValue();
String val_str=recordField.getString();
System.out.print(val_str+" ");
}
System.out.print("\n====================================\n");
}
demo例子