Appearance
SAP RFC对接
1 概述
在SAP系统中,远程调用的能力是由RFC(Remote Function Call的标准通讯方式,即远程函数调用,下文简称RFC)接口系统提供的。RFC允许在两个SAP系统(R/3或者R/2)之间进行调用,或者在一个SAP系统和非SAP系统之间调用。
2 织信如何调用SAP RFC函数
2.1 通过Java扩展库调用SAP RFC函数
调用方法
java
package informat.library.poc;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sap.conn.jco.JCo;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.ext.DestinationDataProvider;
import informat.library.utils.JSONUtil;
public class SapService {
//
private static Logger logger=LoggerFactory.getLogger(SapService.class);
//
public static String getVersion() {
return JCo.getVersion();
}
public static void registerDestinationDataProvider(String destinationName, Map<String,String> properties) {
logger.info("registerDestinationDataProvider destinationName:{}",
destinationName, JSONUtil.toJson(properties));
Properties props=new Properties();
if(properties!=null) {
properties.forEach((k,v)->{
props.setProperty(k,v);
});
}
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(new CustomDestinationDataProvider(destinationName, props));
}
// 通用SAP函数调用方法
public static SapFunctionResult callSapFunction(String destinationName, // SAP目标名称(如"SAP_DEST")
String functionName, // 要调用的函数模块名称
Map<String, Object> inputs, // 输入参数键值对
List<String> outputTables // 需要返回的输出表名称数组(可选)
) throws JCoException {
logger.info("callSapFunction destinationName:{} functionName:"+
destinationName+", functionName"+functionName+","+JSONUtil.toJson(inputs)+",outputTables:"+JSONUtil.toJson(outputTables));
JCoDestination destination = JCoDestinationManager.getDestination(destinationName);
JCoFunction function = destination.getRepository().getFunction(functionName);
if (function == null) {
throw new RuntimeException("SAP函数 " + functionName + " 不存在");
}
// 设置输入参数
if (inputs != null) {
JCoParameterList importParams = function.getImportParameterList();
inputs.forEach((k, v) -> importParams.setValue(k, v));
}
// 执行函数调用
function.execute(destination);
// 处理返回结果
SapFunctionResult result = new SapFunctionResult();
// 获取导出参数
JCoParameterList exportParams = function.getExportParameterList();
if (exportParams != null) {
for (JCoField param : exportParams) {
result.addExportParam(param.getName(), param.getValue());
}
}
// 处理输出表(按需获取)
if (outputTables != null) {
JCoParameterList tables = function.getTableParameterList();
for (String tableName : outputTables) {
if (tables.isActive(tableName)) {
result.addOutputTable(tableName, tables.getTable(tableName));
}
}
}
logger.info("callSapFunction result:{}", JSONUtil.toJson(result));
return result;
}
//
public static void main(String[] args) throws JCoException {
System.out.println(JCo.getVersion());
Map<String,String> props = new HashMap<>();
props.put(DestinationDataProvider.JCO_ASHOST, "your_sap_host"); // SAP服务器地址
props.put(DestinationDataProvider.JCO_SYSNR, "00"); // 系统编号
props.put(DestinationDataProvider.JCO_CLIENT, "100"); // 客户端编号
props.put(DestinationDataProvider.JCO_USER, "username"); // 用户名
props.put(DestinationDataProvider.JCO_PASSWD, "password"); // 密码
props.put(DestinationDataProvider.JCO_LANG, "en"); // 语言
props.put(DestinationDataProvider.JCO_POOL_CAPACITY, "3");
props.put(DestinationDataProvider.JCO_PEAK_LIMIT, "10");
//
String destinationName = "SAP_DEST";
registerDestinationDataProvider(destinationName, props);
Map<String, Object> inputs = new HashMap<>();
// 3. 设置输入参数
inputs.put("AUART", "ZOR1");
inputs.put("ZOAMWLXX", "20_1.05.01.10455");
inputs.put("KUNSP", "100689");
//
List<String> outputTables = List.of( "OT_DATA", "OTHER_TABLE" );
SapFunctionResult result=callSapFunction(destinationName, "ZFM_SD051", inputs, outputTables);
System.out.println(JSONUtil.toJson(result));
}
}
2.2 将java工程打包后上传到织信应用扩展库
2.3 织信脚本调用SAP RFC函数
织信脚本通过informat.system.invokeLibrary调用java扩展库,从而实现调用SAP RFC函数
js
informat.system.invokeLibrary('saplibrary','informat.library.poc.SapService','registerDestinationDataProvider',
["sap_test1",{
"jco.client.ashost":"192.168.x.x",
"jco.client.sysnr":"00",
"jco.client.client":"800",
"jco.client.user":"user",
"jco.client.passwd":"password",
"jco.client.lang":"en",
"jco.destination.pool_capacity":"3",
"jco.destination.peak_limit":"10"
}]);
let result=informat.system.invokeLibrary('saplibrary',
'informat.library.poc.SapService','callSapFunction',
["sap_test1",'ZFM_SD051',
{"AUART":"ZOR1"},['OT_DATA','OTHER_TABLE']]
);
console.log('result',result);
SapFunctionResult结构
java
public class SapFunctionResult {
public Map<String, Object> exportParams = new HashMap<>();
public Map<String, JCoTable> outputTables = new HashMap<>();
}