1、RFC介绍
SAP R/3的接口方式主要有RFC、IDOC、BAPI三种。
RFC分二种:1 正常的本地RFC。2 远程RFC(外部系统调用)。
RFC可以理解成一个函数,它有输入、输出,改变,排除 参数,表(既可以输入也输出)。
这里我们着重介绍一下RFC。
RFC(Remote Function Call,远程功能调用)是SAP系统之间以及SAP与外部系统之间程序通信的基本接口技术,诸多其他更高层的SAP接口和通信技术,如BAPI、ALE等,都是基于RFC实现的。在SAP中,可以提供给其他系统进行远程调用的程序模块是支持RFC的功能模块,即RFM(remote-enabled function module,支持远程调用的功能模块)。
RFC是SAP系统和其他(SAP或非SAP)系统间的一个重要而常用的双向接口技术,也被视为SAP与外部通信的基本协议。简单地说,RFC过程就是系统调用当前系统外的程序模块,从而实现某个功能,而且调用系统和被调用系统中至少有一个必须是SAP ABAP系统。这种远程功能调用也可在同一系统内部进行(如本地SAP系统内的远程调用);但通常情况下,调用程序和被调用程序处于不同系统。
RFC参数的介绍:
Attributes(属性), Import(输入参数),Export(输出参数),Changing(更改参数),Tables(输入,输出内表),Exceptions(排除参数),Source code(编写代码)。
Attributes(属性):
Normal Function Module: 在SAP内部调用RFC
Remote-Enabled Module:远程函数调用,即使用外部系统(.NET,VB,JAVA....)调用SAP RFC。
Update Module:一般使用 Start immed(立刻执行).
Import(输入参数):
就是要传入来的条件参数,不能为内表。最常用。
Export(输出参数):
就是返回值,也不能为内表。最常用。
Changing(更改参数):
返回值,与export差不多,这个很少用。
Tables(输入,输出内表):
可以把多个内表的值传进来,同时也可以把多个内表返回。
Exceptions(排除参数):
不常用。
Source code(编写代码):
就是编写代码了,如果不写代码,那这个RFC就没有用处了。
2、创建函数组
这一步可以不需要,这里的目的主要是怕影响别的函数组。
进入SE37,点击菜单“Goto”-->“Function Groups”-->“Create Group”
输入函数组、描述然后保存、激活
3、创建Function
输入Function名称后,点击Create按钮
选择函数组,输入描述,保存
选择Remote-Enabled Module
设置输入参数
设置输出参数
代码如下
保存激活。
4、SAP内部测试
5、JAVA调用
package com.pcmall; import java.io.File; import java.io.FileOutputStream; import java.util.Properties; import org.apache.log4j.Logger; 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; /** * 与SAP连接配置 * @author jay */ public class SAPConn { private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL"; static{ Properties connectProperties = new Properties(); connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "xxx.xxx.xxx.xxx");//服务器 connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "xxx"); //系统编号 connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx"); //SAP集团 connectProperties.setProperty(DestinationDataProvider.JCO_USER, "xxx"); //SAP用户名 connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "xxx"); //密码 connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "zh"); //登录语言 connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3"); //最大连接数 connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10"); //最大连接线程 createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties); } /** * 创建SAP接口属性文件。 * @param name ABAP管道名称 * @param suffix 属性文件后缀 * @param properties 属性文件内容 */ private static void createDataFile(String name, String suffix, Properties properties){ File cfg = new File(name+"."+suffix); if(cfg.exists()){ cfg.deleteOnExit(); } try{ FileOutputStream fos = new FileOutputStream(cfg, false); properties.store(fos, "for tests only !"); fos.close(); }catch (Exception e){ log.error("Create Data file fault, error msg: " + e.toString()); throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e); } } /** * 获取SAP连接 * @return SAP连接对象 */ public static JCoDestination connect(){ JCoDestination destination =null; try { destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED); } catch (JCoException e) { log.error("Connect SAP fault, error msg: " + e.toString()); } return destination; } private static Logger log = Logger.getLogger(SAPConn.class); // 初始化日志对象 }调用接口代码如下
package com.pcmall; import com.sap.conn.jco.JCoDestination; import com.sap.conn.jco.JCoFunction; import com.sap.conn.jco.JCoParameterList; import com.sap.conn.jco.JCoTable; public class MultiFromSAP { public static void main(String[] args) { JCoFunction function = null; JCoDestination destination = SAPConn.connect(); String sum="";//求和 try { //调用Z_WS_TEST函数 function = destination.getRepository().getFunction("Z_WS_TEST"); JCoParameterList input = function.getImportParameterList(); //NUM1 input.setValue("NUM1", "10"); //NUM2 input.setValue("NUM2", "8"); function.execute(destination); sum= function.getExportParameterList().getString("NUM");//调用接口返回值 System.out.println("求和为:" + sum); }catch (Exception e) { e.printStackTrace(); } } }测试输出结果如下,说明SAP接口已经调通