🍵 Java 调用 SAP RFC 接口「实例」

首页 / 💰笔记 / 正文

前言

首先,作为一个开发人员要清楚:任何专业的事情「最好」要交给专业的人员来做

  • 如果你是一位 ABAP 开发者,并没有 Java 开发经验,那么建议还是找 Java 开发人员来完成该部分的开发,你只需要完成 SAP RFC 函数代码部分即可。
  • 当然如果时间「足够」充裕,你可以先自行学习 Java 相关基础内容,再进行相关操作,避免因为知识储备的缺漏,导致浪费大量的时间在配置和语法上面。

概览

  • B 端 SAP RFC 配置 & 代码
  • C 端 Java 配置
  • C 端 Java 调用
  • 参考文章

RFC 配置

RFC 函数模块 ZMM_OA_MAT_INFO 改为「远程启用」

SAP-Java-RFC-STAIN-01.png

本次实例仅以「调用配置 流程」为主,如下为 简易 DEMO 源码:

FUNCTION zmm_oa_mat_info.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_FLAG) TYPE  INT4 DEFAULT 0
*"  EXPORTING
*"     VALUE(EV_MSGTXT) TYPE  BAPI_MSG
*"     VALUE(EV_MSGTYP) TYPE  BAPI_MSG
*"  TABLES
*"      ET_MARA STRUCTURE  ZMM_INFO_TEST
*"----------------------------------------------------------------------
​
*&--- 供 Java 调用的 SAP RFC 物料测试接口 DEMO
​
  IF iv_flag EQ 1.
    CLEAR: et_mara.
​
    SELECT mara~matnr,
           mara~ersda,
           mara~ernam,
           mara~matkl,
           mara~meins
      INTO CORRESPONDING FIELDS OF TABLE @et_mara
      FROM mara
      UP TO 100 ROWS.
​
  ENDIF.
​
ENDFUNCTION.

代码完成后「激活」函数,至此 SAP 端的所有内容,我们已经配置完成


C 端 Java 配置

测试环境

  • OS: Windows 11
  • Java Version: 1.8.0_301
  • Lib: sapjco3.jar & sapjco3.dll

工程结构

PS: 抹去的部分,为个人测试 DEMO,忽略即可

SAP-Java-RFC-STAIN-02.png

如果你构建的是 Web 项目,那么 lib 文件 放到 WEB-INF/lib 下即可


C 端 Java 调用

PS: 工作之后也习惯了尽量跳过「闭门造车」的阶段
  • 以下 实例使用 @JYs 博主的代码,在此感谢~

构建 Conn 对象:SAPConn.java

package cc.cnix;
​
/**
 * @Author: Wriprin
 * @Date: 2022/11/25 17:04
 * @Version 1.0
 */
public class SapConn {
    // SAP server
    private String JCO_ASHOST;
    // SAP system number
    private String JCO_SYSNR;
    // SAP client
    private String JCO_CLIENT;
    // SAP user name
    private String JCO_USER;
    // SAP user password
    private String JCO_PASSWD;
    // SAP language
    private String JCO_LANG;
    // MAX connection
    private String JCO_POOL_CAPACITY;
    // MAX thread
    private String JCO_PEAK_LIMIT;
    // SAP ROUTER
    private String JCO_SAPROUTER;
​
    public SapConn(String JCO_ASHOST, String JCO_SYSNR, String JCO_CLIENT, String JCO_USER,
                   String JCO_PASSWD, String JCO_LANG, String JCO_POOL_CAPACITY, String JCO_PEAK_LIMIT,
                   String JCO_SAPROUTER) {
        this.JCO_ASHOST = JCO_ASHOST;
        this.JCO_SYSNR = JCO_SYSNR;
        this.JCO_CLIENT = JCO_CLIENT;
        this.JCO_USER = JCO_USER;
        this.JCO_PASSWD = JCO_PASSWD;
        this.JCO_LANG = JCO_LANG;
        this.JCO_POOL_CAPACITY = JCO_POOL_CAPACITY;
        this.JCO_PEAK_LIMIT = JCO_PEAK_LIMIT;
        this.JCO_SAPROUTER = JCO_SAPROUTER;
    }
​
    public SapConn() {
    }
​
    public String getJCO_ASHOST() {
        return JCO_ASHOST;
    }
​
    public void setJCO_ASHOST(String JCO_ASHOST) {
        this.JCO_ASHOST = JCO_ASHOST;
    }
​
    public String getJCO_SYSNR() {
        return JCO_SYSNR;
    }
​
    public void setJCO_SYSNR(String JCO_SYSNR) {
        this.JCO_SYSNR = JCO_SYSNR;
    }
​
    public String getJCO_CLIENT() {
        return JCO_CLIENT;
    }
​
    public void setJCO_CLIENT(String JCO_CLIENT) {
        this.JCO_CLIENT = JCO_CLIENT;
    }
​
    public String getJCO_USER() {
        return JCO_USER;
    }
​
    public void setJCO_USER(String JCO_USER) {
        this.JCO_USER = JCO_USER;
    }
​
    public String getJCO_PASSWD() {
        return JCO_PASSWD;
    }
​
    public void setJCO_PASSWD(String JCO_PASSWD) {
        this.JCO_PASSWD = JCO_PASSWD;
    }
​
    public String getJCO_LANG() {
        return JCO_LANG;
    }
​
    public void setJCO_LANG(String JCO_LANG) {
        this.JCO_LANG = JCO_LANG;
    }
​
    public String getJCO_POOL_CAPACITY() {
        return JCO_POOL_CAPACITY;
    }
​
    public void setJCO_POOL_CAPACITY(String JCO_POOL_CAPACITY) {
        this.JCO_POOL_CAPACITY = JCO_POOL_CAPACITY;
    }
​
    public String getJCO_PEAK_LIMIT() {
        return JCO_PEAK_LIMIT;
    }
​
    public void setJCO_PEAK_LIMIT(String JCO_PEAK_LIMIT) {
        this.JCO_PEAK_LIMIT = JCO_PEAK_LIMIT;
    }
​
    public String getJCO_SAPROUTER() {
        return JCO_SAPROUTER;
    }
​
    public void setJCO_SAPROUTER(String JCO_SAPROUTER) {
        this.JCO_SAPROUTER = JCO_SAPROUTER;
    }
​
    @Override
    public String toString() {
        return "SapConn{" +
                "JCO_ASHOST='" + JCO_ASHOST + ''' +
                ", JCO_SYSNR='" + JCO_SYSNR + ''' +
                ", JCO_CLIENT='" + JCO_CLIENT + ''' +
                ", JCO_USER='" + JCO_USER + ''' +
                ", JCO_PASSWD='" + JCO_PASSWD + ''' +
                ", JCO_LANG='" + JCO_LANG + ''' +
                ", JCO_POOL_CAPACITY='" + JCO_POOL_CAPACITY + ''' +
                ", JCO_PEAK_LIMIT='" + JCO_PEAK_LIMIT + ''' +
                ", JCO_SAPROUTER='" + JCO_SAPROUTER + ''' +
                '}';
    }
}
​

构建 Conn 工具类,负责 客户端 与 SAP 系统的连接:SAPConnUtil.java

package cc.cnix;
​
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
​
import com.sap.conn.jco.*;
import com.sap.conn.jco.ext.DestinationDataProvider;
​
​
/**
 * @Author: Wriprin
 * @Date: 2022/11/25 17:01
 * @Version 1.0
 */
public class SAPConnUtil {
    private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
​
    /**
     * Establish SAP interface
     * @param name  ABAP name
     * @param suffix    file suffix
     * @param properties    file content
     */
    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){
            System.out.println("Create Data file fault, error msg: " + e.toString());
            throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
        }
    }
​
    /**
     * Init SAP connection
     */
    private static void initProperties(SapConn sapConn) {
        Properties connectProperties = new Properties();
        // SAP server location
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, sapConn.getJCO_ASHOST());
        // SAP system number
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  sapConn.getJCO_SYSNR());
        // SAP client
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, sapConn.getJCO_CLIENT());
        // SAP user ID
        connectProperties.setProperty(DestinationDataProvider.JCO_USER,   sapConn.getJCO_USER());
        // SAP user PW
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, sapConn.getJCO_PASSWD());
        // SAP language
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   sapConn.getJCO_LANG());
        // MAX connection
        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, sapConn.getJCO_POOL_CAPACITY());
        // MAX connection threads
        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, sapConn.getJCO_PEAK_LIMIT());
        // SAP ROUTER
        connectProperties.setProperty(DestinationDataProvider.JCO_SAPROUTER, sapConn.getJCO_SAPROUTER());
​
        createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
    }
​
    /**
     * Get SAP connection
     * @return  SAP connection object
     */
    public static JCoDestination connect(SapConn sapConn){
        System.out.println("Connecting to SAP...");
        JCoDestination destination = null;
        initProperties(sapConn);
        try {
            destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
            destination.ping();
            System.out.println("Connection established.");
        } catch (JCoException e) {
            System.out.println("Connect SAP fault, error msg: " + e.toString());
        }
        return destination;
    }
}
​

主程序,调用测试:GetMaraInfo.java

※ 请注意:

  • 如果你是通过 VPN 的方式连接 SAP 系统,那么 JCO_HOST 请配置 公网 IP,并无需配置 JCO_SAPROUTER
  • 如果你是通过 Router 的方式连接 SAP 系统,那么 JCO_HOST 请配置 内网 IP,并需要配置 JCO_SAPROUTER
package cc.cnix;
​
import com.sap.conn.jco.*;
​
/**
 * @Author: Wriprin
 * @Date: 2022/11/25 17:20
 * @Version 1.0
 */
public class GetMaraInfo {
    public static void main(String[] args) throws JCoException {
​
        // Configuration of SAP connection
        String JCO_HOST = "xxx.xx.xx.xxx";
        String JCO_SYNSNR = "00";
        String JCO_CLIENT = "xxx";
        String JCO_USER = "xxx";
        String JCO_PASSWD = "xxx";
        String JCO_LANG = "ZH";
        String JCO_POOL_CAPACITY = "30";
        String JCO_PEAK_LIMIT = "100";
        String JCO_SAPROUTER = "/H/xxx.xx.xx.xxx/...";
​
        SapConn con = new SapConn(JCO_HOST, JCO_SYNSNR, JCO_CLIENT, JCO_USER, JCO_PASSWD, JCO_LANG, JCO_POOL_CAPACITY, JCO_PEAK_LIMIT, JCO_SAPROUTER);
        JCoDestination jCoDestination = SAPConnUtil.connect(con);
​
        try {
            // 获取调用 RFC 函数对象
            JCoFunction func = jCoDestination.getRepository().getFunction("ZMM_OA_MAT_INFO");
​
            // 配置传入参数
            JCoParameterList importParameterList = func.getImportParameterList();
            importParameterList.setValue("IV_FLAG", 1);
​
            // 调用并获取返回值
            func.execute(jCoDestination);
            // 获取 内表 - ET_MARA
            JCoTable maraTable = func.getTableParameterList().getTable("ET_MARA");
​
            // 循环输出 Table 数据
            for (int i = 0; i < maraTable.getNumRows(); i++) {
                maraTable.setRow(i);
​
                String matnr = maraTable.getString("MATNR");
                String esdra = maraTable.getString("ERSDA");
                String ernam = maraTable.getString("ERNAM");
                String matkl = maraTable.getString("MATKL");
                String meins = maraTable.getString("MEINS");
​
                System.out.println("物料编号:" + matnr + " - 创建日期:" + esdra + " - 创建人:" + ernam + " - 物料组:" + matkl + " - 单位:" + meins);
            }
​
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
​

测试结果,如下图所示:

SAP-Java-RFC-STAIN-03.png


参考文章

您阅读这篇文章共花了:
打赏
评论区
头像
文章目录