JAVA 调用 SAP RFC接口【函数】的方式实例【window 和Linux不同部署】

java要调用  SAP RFC接口时,需要用到sapjco3.jar 架包;

网上说的乱八七糟的windowssapjco3.dll 文件放到system32的目录下.............我嫌弃麻烦没用;

本人经历亲测可用的简单粗暴的方式:

先说windows下还需要将文件sapjco3.dll 和 sapjco3.jar文件放到项目下WEB-INF/lib 下直接就可以用。

此时tomcat/bin下面会生成一个文件【*****.jcoDestination】如果测试-正式切换的时候,这个不会变,要手动更改。

【Java 调用sap 切换正式怎么还是测试的问题】{ 后面会讲解到!}

  Linux别急下面再详细说一下Linux的配置,坑的要死。。。(各种百度各种查)

下载链接:链接:https://pan.baidu.com/s/1dFKyvldScvXxIXP18nmtpA 
提取码:cvde

不乐意挣这个csdn币 直接放百度云,有用的话给个双击就行

java项目下直接把sapjco3.jar 和sapjco3.dll 两个文件da放到 项目lib下

直接上代码:连接sap

package com.jeecg.sapjco;
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;
import org.jeecgframework.core.annotation.JAuth;
import org.jeecgframework.core.enums.Permission;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;

@JAuth(auth= Permission.SKIP_AUTH) //跳过外部调用拦截
public class GetSapConn {

   
    static String ABAP_AS_POOLED = "SAP-RFC"; //所属异构系统 【找sap要】
    private static void createDataFile() {
        Properties properties = new Properties();
        //测试
       properties.setProperty(DestinationDataProvider.JCO_ASHOST, "**.**.**.***");//sap服务器地址
       properties.setProperty(DestinationDataProvider.JCO_SYSNR, "02");//系统编号,找SAP核对写00就可以了
        properties.setProperty(DestinationDataProvider.JCO_CLIENT, "6**");//集团号,不知道就问你们的sap basis
        properties.setProperty(DestinationDataProvider.JCO_USER, "***");//帐号
        properties.setProperty(DestinationDataProvider.JCO_PASSWD, "****");//密码
       properties.setProperty(DestinationDataProvider.JCO_LANG, "zh");//语言


        String name = ABAP_AS_POOLED;
        String suffix = "jcoDestination";
        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) {
                throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
            }
        }

    }

    public static JCoDestination getJcoConnection() throws JCoException {
        createDataFile();
        return JCoDestinationManager.getDestination(ABAP_AS_POOLED);
    }

}

测试案例【传入参数调用sap函数返回结果】

package com.jeecg.sapjco;

import com.jeecg.roomRecord.entity.TAWorkroomRecordEntity;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoTable;
import org.jeecgframework.core.annotation.JAuth;
import org.jeecgframework.core.common.controller.BaseController;
import org.jeecgframework.core.common.model.json.AjaxJson;
import org.jeecgframework.core.constant.Globals;
import org.jeecgframework.core.enums.Permission;
import org.jeecgframework.minidao.annotation.Param;
import org.jeecgframework.web.cgform.exception.BusinessException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/SapTest")
@JAuth(auth= Permission.SKIP_AUTH)
public class SapTest extends BaseController {
    /**
     *
     * @param request
     * @return
     *
     *  Sap 函数:ZFI_FM_009
     */
    @RequestMapping(params = "test")
    @ResponseBody
    public AjaxJson test(HttpServletRequest request) {
        String message = null;
        AjaxJson j = new AjaxJson();
        try {
            JCoDestination jCoDestination = null;// 连接对象
            JCoFunction function = null;// 调用rfc函数对象
            try {
                jCoDestination=GetSapConn.getJcoConnection();
                 调用rfc-sap【ZFI_FM_009】函数对象--指的是调用sap 那边的函数名
                function = jCoDestination.getRepository().getFunctionTemplate("ZFI_FM_009").getFunction();
                if (null == function) {
                    throw new RuntimeException("get function not found in sap");
                } else {
                    JCoParameterList paramList = function.getImportParameterList();
                    //【sap系统传入参数,有多个的话就写多行 LV_BANKA sap定义的函数参数名 有多个的话就写多行】
                    paramList.setValue("LV_BANKA","参数值");
                    paramList.setValue("LV_BANKL","参数值");
                    //如果传如参数是内表的形式的话就以如下代码传入sap系统
                    //  JCoTable table1 = function.getTableParameterList().getTable("I_EKPO");
                    //  for (int i = 0; i < purchaseNo.size(); i++) {
                    // table1.setRow(i);
                    // table1.appendRow();
                    // table1.setValue("EBELN", purchaseNo.get(i)[0]);
                    // table1.setValue("EBELP", purchaseNo.get(i)[1]);
                    //  }
                    function.execute(jCoDestination);//执行调用函数
                    JCoTable table2 = function.getTableParameterList().getTable("ES_DATA");//[ES_DATA 是SAP返回 数据的“表名字”]得到sap返回的参数,你就把他当作c语言的结构体理解就可以了
                    //有时候sap那边只是返回一个输出参数,sap比方说你这边输入一个物料号,想得到sap那边的物料描述,这是sap方是不会返回一个内表给你的
                    //而是只是返回一个输出参数给你这时你就要用到下面的方法来得到输出参数
                    //paramList = function.getExportParameterList();
                    //paramList.getString("rfc返回字段字段名称");
                    for (int i = 0; i < table2.getNumRows(); i++) {
                        table2.setRow(i);
                         //这里获取sap函数传出内表结构的字段 【传入的字符串为调用函数需要传入的参数名,必须为大写】
                        String BANKL = table2.getString("BANKL");//【表结果里面的字段】记住这里BANKL一定是大写的,不然得不到值
                        String BANKA = table2.getString("BANKA");//【表结果里面的字段】记住这里BANKA一定是大写的,不然得不到值
                        System.out.println("BANKL:"+BANKL  +"------"+ "BANKA"+BANKA);
                        //得到了sap数据,然后下面就是你java擅长的部分了,想封装成什么类型的都由你
                    }
                }
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } finally {
                jCoDestination = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            message = "失败";
            throw new org.jeecgframework.core.common.exception.BusinessException(e.getMessage());
        }
        j.setMsg(message);
        return j;
    }
}

执行结果:

如果是 普通参数(相当于java 方法传入一个字符串 )  +   结构参数的话  说白了结构类型就相当于java传入一个Map

/**
     * IV_TYPE
     * IV_IS_COMMIT
     * IS_DATA [结构类型]
     * OA存储主数据存储接口--结构类型
     * ZSD_FM_CREATE_CUSTOMER
     * chufangbo 2020-04-11
     */
    @RequestMapping(params = "get***SAP***Function")
    @ResponseBody
    public AjaxJson getSapBackFunction(HttpServletRequest request) {
        //TDingOaInfoEntity entity = JSONObject.parseObject(jsonObject, TDingOaInfoEntity.class);
        String message = null;
        AjaxJson j = new AjaxJson();
            try {
                    JCoDestination destination = JCoDestinationManager
                            .getDestination(ABAP_AS);//所属异构系统OA或者SAP提供
                    JCoFunction function = destination.getRepository().getFunction(
                            "ZSD_FM_*******");//从对象仓库中获取 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());
                    }
                JCoParameterList is_data_sum = function.getImportParameterList();
                is_data_sum.setValue("IV_TYPE","1");// 普通参数
                is_data_sum.setValue("IV_IS_COMMIT","X");// 普通参数
                //IS_DATA 是SAP 结构名称 类是与JAVA Map当参数传入Funtion的参数封装
                JCoStructure is_data = function.getImportParameterList().getStructure("IS_DATA");

                is_data.setValue("KTOKD","***");// KTOKD 是结构中的名称类似于java 传入一个map,在此处通过key赋值value进行封装
                //.............继续添加
          
                is_data_sum.setValue("IS_DATA",is_data);
                function.execute(destination);//执行调用函数
                JCoTable table2 = function.getTableParameterList().getTable("MESSTAB");//[MESSTAB 是SAP返回 数据的“表名字”]得到sap返回的参数,你就把他当作c语言的结构体理解就可以了
                //有时候sap那边只是返回一个输出参数,sap比方说你这边输入一个物料号,想得到sap那边的物料描述,这是sap方是不会返回一个内表给你的
                //而是只是返回一个输出参数给你这时你就要用到下面的方法来得到输出参数
                //获取sap回执编号
                JCoParameterList exportParameterList = function.getExportParameterList();
                Object ev_kunnr = exportParameterList.getValue("EV_KUNNR");
                System.out.println("获取SAP回传客户编号: "+ev_kunnr);

                for (int i = 0; i < table2.getNumRows(); i++) {
                    table2.setRow(i);
                    //这里获取sap函数传出内表结构的字段 【传入的字符串为调用函数需要传入的参数名,必须为大写】
                    String TYPE = table2.getString("TYPE");//[消息类型:S 成功 E 错误 W警告 I信息 A 中断]记住这里参数一定是大写的,不然得不到值【如果报错说明你参数传的不对】
                    String MESSAGE = table2.getString("MESSAGE");//记住这里一定是大写的,不然得不到值
                    System.out.println("TYPE:"+TYPE +"MESSAGE:"+MESSAGE);
                }


            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

        j.setMsg(message);
        return j;
    }

开始Linux :

首先不要依靠以上配置,和百度所说的去Linux去配置环境变量什么的。。。都没用。。。害我南辕北辙,ca踩了一个坑,跳出来又踩进去,又跳出来,又踩进去。。。。。

开始正文

  找到Linux项目中的Tomcat         /home/...../apache-tomcat-dd/webapps/项目名称/WEB-INF/lib

  第一步 把以下三个文件丢进去。sapjcorfc 这两个文件,看网上说的天花乱坠的我是没用到。

第二步:找到 /home/......./apache-tomcat-dd/bin

     

  把这两个文件丢进去,然后重新启动项目

 然后你会发现 在bin目录下面生成一个 类是与   SAP-RFC.jcoDestination  

 注释:SAP-RFC是我调用sap那边定义的所属异构系统的名字,不用管,你们可能生成的别的名字

      另外【如果本地测试之后没问题,或者到服务器上测试没问题的话,切换到正式连接之后发现数据还是测试库的,憋着急,此时请查看本地Tomcat 和服务器上tomcat/bin 目录下的SAP-RFC.jcoDestination ,的地址配置的还是测试库的,修改保存一下就OK了】

 如果你们没生成,等会我在文章最开始的百度云放一个,你们模仿写一下你们自己的配置。添加进去。这个东西很重要,如果没有就会调用失败。

   大致就是:(你们可以自己写一个方进去SAP-RFC是我调用sap那边定义的 你们用你们自己的

   #for tests only !
   #Mon Apr 20 11:03:50 CST 2020
   jco.client.lang=zh
   jco.client.client=***
   jco.client.passwd=***
   jco.client.user=*****
   jco.client.sysnr=0*
   jco.client.ashost=2*.2*.2*.2**

大功告成:

注释:如果SAP那边报错

可能就是通过JAVA传输的时候 sap 那边不支持 Null,此时你可以debug 查看一下 然后用三元运算符赋值为 空串。

打包的时候记得打进项目

  <build>       
      <resources>
           
            <resource>
                //根据自己存放的目录
                <directory>src/main/lib</directory>
                <includes>
                    <include>**/*.jar</include>
                </includes>
                <targetPath>lib</targetPath>
            </resource>
        </resources>
  </build>

新增方法:获取SAP内表结构,并进行赋值传递到SAP更新数据(根据工号NO 更新邮箱 EMAIL)

 @RequestMapping(value = "test",method = RequestMethod.POST)
    public AjaxJson updateUserInformationToSap(@RequestBody  JSONArray jsonStr){
        System.out.println(jsonStr);
        try{
            JCoDestination jCoDestination = null;
            JCoFunction function = null;
            jCoDestination = GetSapConn.getJcoConnection();
            function = jCoDestination.getRepository().getFunctionTemplate("ZHRFM_BINPUT").getFunction();
            if (null == function) {
                throw new RuntimeException("get function not find in sap system");
            }else {
                //如果传如参数是内表的形式的话就以如下代码传入sap系统
                JCoTable is_data = function.getTableParameterList().getTable("T_0105");
                for (int i = 0; i < jsonStr.size(); i++) {
                    is_data.setRow(i);
                    is_data.appendRow();
                    is_data.setValue("NO",jsonStr.getJSONObject(i).getString("NO"));
                    is_data.setValue("FLAG",jsonStr.getJSONObject(i).getIntValue("GLAG"));
                    is_data.setValue("EMAIL",jsonStr.getJSONObject(i).getString("EMAIL"));
                   
                }
                function.execute(jCoDestination);//执行调用函数
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return  AjaxJson.success();
    }

  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
调用 SAPRFC 接口,需要使用 SAP 提供的 Java Connector(SAP JCo)库。在使用 SAP JCo 调用 RFC 接口时,需要在 SAP JCo 的配置文件中设置系统 ID(System ID),以便正确地连接到 SAP 系统。 要配置 SAP JCo 的系统 ID,需要进行以下步骤: 1. 打开 SAP JCo 的配置文件 sapjco3.properties,该文件通常位于应用程序的 classpath 下。 2. 在 sapjco3.properties 文件中添加以下配置项: ``` jco.client.sysnr=<系统编号> jco.client.client=<客户端> jco.client.user=<用户名> jco.client.passwd=<密码> jco.client.lang=<语言> jco.client.ashost=<应用服务器主机名> jco.client.saprouter=<SAP 路由器> ``` 其中,<系统编号> 是 SAP 系统的编号,<客户端> 是 SAP 客户端的编号,<用户名> 和 <密码> 是 SAP 用户的登录信息,<语言> 是登录时使用的语言代码,<应用服务器主机名> 是 SAP 应用服务器的主机名,<SAP 路由器> 是可选的 SAP 路由器配置。 3. 在 Java 代码中使用 SAP JCo 的 API 调用 RFC 接口时,可以使用以下代码获取 SAP JCo 的配置信息: ``` JCoDestination destination = JCoDestinationManager.getDestination("<destination>"); ``` 其中,<destination> 是 SAP JCo 的目标名称,可以在 sapjco3.properties 文件中配置。 4. 使用 SAP JCo 的 API 调用 RFC 接口时,需要使用 SAP JCo函数模块名称和函数模块的输入参数,例如: ``` JCoFunction function = destination.getRepository().getFunction("<function_module>"); if (function == null) { throw new RuntimeException("<function_module> not found in SAP system."); } function.getImportParameterList().setValue("<parameter_name>", "<parameter_value>"); function.execute(destination); ``` 其中,<function_module> 是 SAP RFC 函数模块的名称,<parameter_name> 和 <parameter_value> 是函数模块的输入参数名称和值。 以上是 Java 调用 SAP RFC 接口时配置系统 ID 的基本步骤。具体的配置和调用方法可能会因不同SAP 系统和 RFC 接口而有所不同,需要根据实际情况进行调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值