Java直接调用SAP函数详解---Windows篇

3,199 阅读3分钟

Java与SAP之间进行交互有好多解决方案,比如:通过EAI中间平台、WebService接口、SAP JCo组件等等。本文主要介绍在Windows下通过SAP JCo组件实现Java可以直接调用SAP函数。

SAP JCo 的全称是SAP Java Connector(JCo)是SAP提供的一套高效的基于RFC的APAP和Java进程间的通讯组件。

此前使用该组件开发接口,简单测试了下,效率也是很不错的,有个传输数据的接口,在测试环境简单试了试,三万条数据3秒(非压测环境)。

JCo3.0安装

可以根据自己电脑是32位的还是64位的到官网进行下载 官网:service.sap.com/connectors

我这有64位的资源,放置到了百度网盘上,文章底部有公众号二维码,公众号内回复【SAPJCo3】获取

主要就是两个文件:

  • sapjco3.dll
  • sapjco3.jar

在Windows环境下,配置非常简单:

  • 将sapjco3.dll和sapjco3.jar文件文件放入JDK的lib目录下(连接池方式)

  • 将sapjco3.dll文件放入C:\Windows\System32目录下

如何测试是否配置成功呢?

可以在命令窗口下,进入JDK的lib目录,运行下面的命令:

java -jar sapjco3.jar

成功后会弹出下图:

这样在Windows下用Java去连接SAP提供的函数就可以了。

另外,还有一个工具也可以连接SAP,就是--Kettle

配置也非常简单

  • Windows下配置

    将sapjco3.jar拷贝至data-intergration/lib下,sapjco3.dll拷贝至data-intergration/libswt/相应系统下即可

  • Linux下配置

    将sapjco3.jar,libsapjco3.so拷贝至data-integration/libswt/linux/x86_64下即可

应用实例

在Web项目中,使用该组件,需要先创建jcoDestination配置文件,SAPJCo3插件会自动去解析创建连接,以及自动关闭连接,不需要手动进行处理。

现在项目大部分都是maven或者gradle来进行管理,项目中需要增加对sapjco3的依赖

配置文件

创建一个类,用于配置生成连接文件,只展示了部分代码示例,全部类信息传到百度网盘,下载后可以直接使用,有需要公众号回复【SAPJCo3】自取

//......  ....... 

private static final String ABAP_AS_SAP800 = "ABAP_AS_SAP";
  static{
    Properties connectProperties = new Properties();    
    connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "X.X.X.X");//服务器
    connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  "00");        //系统编号
    connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "800");       //SAP集团
    connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "name");  //SAP用户名
    connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password");     //密码
    connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "ZH");        //登录语言
    connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");  //最大连接数
    connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");     //最大连接线程
    
    createDataFile(ABAP_AS_SAP, "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 connection !");
      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系统给出的函数以及入参、出参后,就可以使用JCo进行接口开发了,下面是在接口开发过程中常用的方法,基本够用,不够的可以去查询JCo的官方文档。

//获取要连接的SAP配置文件名,这个名需要配置到环境资源文件中,这样就可以通过打包来区别开连接SAP的不同环境
//此处为方面看,直接写上具体值
private static final String ABAP_AS_SAP = "ABAP_AS_SAP";
//创建与SAP的连接
JCoDestination dest = JCoDestinationManager.getDestination(ABAP_AS_SAP);
//获取repository
JCoRepository repository = dest.getRepository();
//获取函数信息
JCoFunction fm = repository.getFunction("函数名");
if (fm == null) {
   throw new RuntimeException("Function does not exists in SAP system.");
}
//获取输入参数
JCoParameterList input = fm.getImportParameterList();
//根据接口文档,可以知道入参,设置查询参数
//这个是函数的入参是单独的,而不是有表的情况
input.setValue("param1", value1);
input.setValue("param2", value2);
.......
//有表的情况,需要先获取表信息
JCoTable inTableWerks = jCoFunction.getTableParameterList().getTable("表名");
//一般有表的情况,都是可以传List的,所以可以循环往表中存参数
for (int i = 0; i < list.length; i++) {
    //附加表的最后一个新行,行指针,它指向新添加的行。
    inTableWerks.appendRow();
    inTableWerks.setValue("param", list[i]);
}
//执行函数
JCoContext.begin(jCoDestination);
jCoFunction.execute(jCoDestination);
JCoContext.end(jCoDestination);
//获取返回的Table
JCoTable outTableOutput = jCoFunction.getTableParameterList().getTable("表名");
//从输出table中获取每一行数据
if (outTableOutput != null && outTableOutput.getNumRows() > 0) {  
  //循环取table行数据
  for (int i = 0; i < outTableOutput.getNumRows(); i++) { 
    //设置指针位置
    outTableOutput.setRow(i);
    System.out.println(outTableOutput.getString("Param1"));
    System.out.println(outTableOutput.getString("Param2")); 
   } 
}

有任何问题欢迎关注公众号【Hugh的白板】私信我,一起探讨,一起学习