参考了作者zfswff的资料

SAP

JCo3.0是Java语言与ABAP语言双向通讯的中间件。与之前1.0/2.0相比,是重新设计的产品。API和架构设计与NCo3.0比较类似,前面也说过,NCo3.0的设计参考了JCo3.0。从本篇开始,系统介绍JCo3.0编程的技术要点。

JCo3.0 安装

下载JCo3.0,注意下载的时候根据操作系统和JVM版本(32位还是64)选择不同的版本。安装就是解压,将文件解压到目标文件夹。以Windows系统为例,主要的文件包括:

sapjco3.dll
sapjco3.jar

SAP强烈推荐将这两个文件放在同一文件夹下。
测试安装是否成功,可以在命令窗口下,进入安装文件夹,运行下面的命令:
java -jar sapjco3.jar

JCoDestination

JCoDestination代表后台SAP系统,程序员不用关心与SAP的连接,jco3.0运行时环境负责管理连接和释放连接。我们先以一个简单的例子看看jco3.0 JCoDestination类的一些要点。

我使用的编程环境是Eclipse,环境准备如下:

  1. 新建一个spring boot项目,项目名为JCo3Demo。

  2. 将sapjco3.jar加入到项目的resources下lib(新建)中。注意前面所说的sapjco3.jar和sapjco3.dll(不需要build path)要放在同一个文件夹下。

  3. 创建实体类SapConn用来存储对接的SAP系统的连接参数,代码如下:

     // SAP服务器private String JCO_ASHOST;// SAP系统编号private String JCO_SYSNR;// SAP集团private String JCO_CLIENT;// SAP用户名private String JCO_USER;// SAP密码private String JCO_PASSWD;// SAP登录语言private String JCO_LANG;// 最大连接数private String JCO_POOL_CAPACITY;// 最大连接线程private String JCO_PEAK_LIMIT;// SAP ROUTERprivate 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;}@Overridepublic 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 + '\'' +'}';}
    
  4. 获取 JCoDestination 的工具类,通过new SAPConnUtils().jCoDestination创建链接并获取JCoDestination类,并且项目根目录下会生成配置文件ABAP_AS_WITH_POOL.jcoDestination,之后可以使用jCoDestination= JCoDestinationManager.getDestination("ABAP_AS_WITH_POOL");获取

     private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";public JCoDestination jCoDestination;public SAPConnUtils(){SapConn con = new SapConn("xxxxx","00","300","xxx","xxxxx","zh","30","150","xxxxxxxxx");jCoDestination = connect(con);}/*** 创建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){System.out.println("Create Data file fault, error msg: " + e.toString());throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);}}/*** 初始化SAP连接*/private static void initProperties(SapConn sapConn) {Properties connectProperties = new Properties();// SAP服务器connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, sapConn.getJCO_ASHOST());// SAP系统编号connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  sapConn.getJCO_SYSNR());// SAP集团connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, sapConn.getJCO_CLIENT());// SAP用户名connectProperties.setProperty(DestinationDataProvider.JCO_USER,   sapConn.getJCO_USER());// SAP密码connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, sapConn.getJCO_PASSWD());// SAP登录语言connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   sapConn.getJCO_LANG());// 最大连接数connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, sapConn.getJCO_POOL_CAPACITY());// 最大连接线程connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, sapConn.getJCO_PEAK_LIMIT());// SAP ROUTERconnectProperties.setProperty(DestinationDataProvider.JCO_SAPROUTER, sapConn.getJCO_SAPROUTER());createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);}/*** 获取SAP连接* @return  SAP连接对象*/public static JCoDestination connect(SapConn sapConn){System.out.println("正在连接至SAP...");JCoDestination destination = null;initProperties(sapConn);try {destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);destination.ping();System.out.println("已成功建立sap的连接");} catch (JCoException e) {System.out.println("Connect SAP fault, error msg: " + e.toString());}return destination;}
    

    }

JCo3.0调用SAP函数的过程

大致可以总结为以下步骤:

  • 连接至SAP系统(参考上面3和4步骤)
  • 创建JcoFunction接口的实例(这个实例代表SAP系统中相关函数)
  • 设置importing参数
  • 调用函数
  • 从exporting参数或者table参数获取数据

JCoFunction接口说明

  • JCoFunction是一个接口,代表SAP系统的函数

  • JCoFunction包含importing参数,exporting参数,changing参数,table参数。分别使用getImportParameterList方法,getExportParameterList方法,getChangingParameterList方法和getTableParameterList获得。这些方法的返回值都是JCoParameter类型

  • JCoFunction.execute方法实际执行函数

如何创建JCoFunction对象

  • 上面的代码是第一种创建JCoFunction实例的方法,BAPI_COMPANYCODE_GETDETAIL为调用函数名:
 JCoRepository repository = dest.getRepository();    JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");
  • 如果我们不关心JCoRepository,也可以这样写:
 JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");
  • 第三种方法是使用JCoFunctionTemplate.getFunction方法,JCoFunctionTemplate也是一个接口,代表SAP函数的meta-data。
  JCoFunctionTemplate fmTemplate= dest.getRepository().getFunctionTemplate("BAPI_COMPANYCODE_GETDETAIL");JCoFunction fm = fmTemplate.getFunction();

设置importing参数

         //调用function函数function = jCoDestination.getRepository().getFunction("调用函数名");//ParamKey为的参数名,以逗号隔开,ParamValue为参数名对应的参数值,if("".equals(ParamKey) || "".equals(ParamValue)) {// 不需要参数}else{String[] paramKeys = ParamKey.split(",");String[] paramValues = ParamValue.split(",");for (int i = 0; i < paramKeys.length; i++) {function.getImportParameterList().setValue(paramKeys[i],"null".equals(paramValues[i]) ? "" : paramValues[i]);}}function.execute(jCoDestination);//提交

设置exporting参数,获取结果

Integer retCode=function.getExportParameterList().getInt("RET_CODE");

设置table参数

Table参数作为export parameter

JCo中,与表参数相关的两个接口是JCoTable和JCoRecordMetaDta, JCoTable就是RFM中tabl参数,而JCoRecordMetaDta是JCoTable或JCoStructure的元数据。

 //ET_LOG为table名JCoTable jcoTable=function.getTableParameterList().getTable("表名");//要点说明:对JCoTable,输出表头和行项目。//表头通过获取JCoTable的JCoRecordMetaData,然后使用JCoRecordMetaData的getName()方法JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();for(int i = 0; i < tableMeta.getFieldCount(); i++){System.out.print(String.format("%s\t", tableMeta.getName(i)));}System.out.println(); // new line//获取表体//JCoTable每一行都是一个JCoStructure,可以通过setRow()设置指针的位置,然后再遍历各个field:for(int i = 0; i < jcoTable.getNumRows(); i++){// Sets the row pointer to the specified position(beginning from zero)jcoTable.setRow(i);//每次一张表// Each line is of type JCoStructurefor(JCoField fld : jcoTable){System.out.println(String.format("%s\t%s",fld.getName(),fld.getString()));}System.out.println();}

Table参数作为import parameter

table作为输入参数,主要解决填充table的问题,基本模式如下:
someTable.appendRow();
someTable.setValue("FLDNAME", someValue);
以RFC_READ_TABLE为例,读取表.

    /*** Shows how to process JCoTable (as importing)*/JCoFunction fm = dest.getRepository().getFunction("RFC_READ_TABLE");// table we want to query is USR04// which is user authorization table in SAPfm.getImportParameterList().setValue("QUERY_TABLE", "USR04");// output data will be delimited by commafm.getImportParameterList().setValue("DELIMITER", ",");// processing table parametersJCoTable options = fm.getTableParameterList().getTable("OPTIONS");// modification date >= 2012.01.01 and <= 2015.12.31options.appendRow();options.setValue("TEXT", "MODDA GE '20120101' ");options.appendRow();options.setValue("TEXT", "AND MODDA LE '20151231' ");// We only care about fields of [user id] and [modification date]        String[] outputFields = new String[] {"BNAME", "MODDA"};JCoTable fields = fm.getTableParameterList().getTable("FIELDS");int count = outputFields.length;fields.appendRows(count);for (int i = 0; i < count; i++){fields.setRow(i);fields.setValue("FIELDNAME", outputFields[i]);            }fm.execute(dest);JCoTable data = fm.getTableParameterList().getTable("DATA");return data;

在代码中我们使用了两种方法来插入table的行项目,第一种方法:

JCoTable options = fm.getTableParameterList().getTable("OPTIONS");
// modification date >= 2012.01.01 and <= 2015.12.31
options.appendRow();
options.setValue("TEXT", "MODDA GE '20120101' ");
options.appendRow();
options.setValue("TEXT", "AND MODDA LE '20151231' ");

第二种方法:

String[] outputFields = new String[] {"BNAME", "MODDA"};
JCoTable fields = fm.getTableParameterList().getTable("FIELDS");
int count = outputFields.length;
fields.appendRows(count);
for (int i = 0; i < count; i++){fields.setRow(i);fields.setValue("FIELDNAME", outputFields[i]);
}

JCoTable重要方法总结

sapjco3 开发与部署环境设置(以下没验证,网上资料)

链接

windows 环境设置

1. sapjco3.dll 需要与 sapjco3.jar 在同一目录
2. 设置系统环境变量,将sapjco3所在目录加入系统环境变量
3. 根据自己的操作系统版本选择对应的sapjco3包

32位系统

例如:
新建环境变量
变量名: JAVA_SAPJCO
变量值: E:\sapjco3\sapjco3-win32
将新建的 JAVA_SAPJCO 环境变量加入 系统环境变量 Path变量集合中.
%JAVA_SAPJCO%\sapjco3.jar

项目部署运行

32位系统 将 sapjco3.dll 加入到c:/windows/system32/目录 或者 将 sapjco3.dll 加入到 JDK/bin 目录下
64位系统将 sapjco3.dll 加入到c:/windows/SysWOW64/目录 或者 将 sapjco3.dll 加入到 JDK/bin 目录下

部署异常问题

1.问题
异常信息 Can’t load IA 64-bit .dll on a AMD 64-bit platform
项目编译及运行,根据自己的操作系统版本选择对应的sapjco3包
2.问题
报错 java.lang.UnsatisfiedLinkError: no sapjco3 in java.library.path ,
是因为没有找到 sapjco3.dll这个库的路径,安装了JDK的环境中,这个库默认的位置不是在system32下,而是在 JDK/JRE/BIN下面。

sapjco3 开发环境设置

1.开发中需要将sapjco3.jar加入到项目的build path中
2.或者将其加入 本地 maven 库

mvn install:install-file -DgroupId=org.hibersap -DartifactId=sapjco3 -Dversion=3.0 -Dpackaging=jar -Dfile=E:/sapjco3/sapjco3-win32/sapjco3.jar

用以替换 org.hibersap 加载项下载的文件

<dependency><groupId>org.hibersap</groupId><artifactId>sapjco3</artifactId><version>3.0</version>
</dependency>

Linux环境设置

Linux java 环境设置

1.创建目录

mkdir /usr/java

2.把下载的rpm文件copy过去

cp jdk-8u161-linux-x64.rpm /usr/java/

3.进入目录

cd /usr/java

4.添加可执行权限

chmod +x jdk-8u161-linux-x64.rpm

5.执行rpm命令安装

rpm -ivh jdk-8u161-linux-x64.rpm

6.查看是否安装成功

java -version

Linux sapjco3 环境设置

1.解压 sapjco3-linux64 或 sapjco3-linuxintel-3.0.5 当前生产环境 centos_X64_32 系统使用的是 sapjco3-linux64
2.将sapjco3.jar 文件复制至 $JAVA_HOME/lib/sapjco3.jar
3.将 libsapjco3.so 文件复制至 $JAVA_HOME/jre/lib/amd64/server/libsapjco3.so
4.设置环境变量

    vim /etc/profile //修改文件
 JAVA_HOME=/usr/local/javaPATH=$PATH:$JAVA_HOME/binCLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/sapjco3.jarJRE_HOME=$JAVA_HOME/jreLD_LIBRARY_PATH=dir:$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/amd64/serverexport JAVA_HOME LD_LIBRARY_PATH PATH

5.刷新配置
source /etc/profile
6.配置本地 hosts 将主机名字映射到IP地址
1.控制台执行 hostname 命令查看计算机名
2.控制台执行 hostname -i 查看本机IP
3.编辑hosts文件 vi /etc/hosts
4.在 /etc/hosts中 加入
192.168.1.10(本机IP) localhost hostname(计算机名)

建立 Jco Serever 监听服务时相关设置windows jco 监听设置

进入 %SystemRoot%\System32\drivers\etc
1.修改 services文件,在services文件尾部 将  jco.server.gwserv:sapgw00 属性值 sapgw00 加入 SAP 端口映射sapdp00  3200/tcp #SAP Serversapgw00  3300/tcp #SAP Gateway
2.修改 hosts文件,在 hosts中 将 jco.server.gwhost:gmdev01  属性值  gmdev01 加入 SAP服务器IP 地址映射10.86.95.121       gmdev01
3.具体示例参考项目目录内的 services/hosts 文件

linux jco 监听设置

 1.执行  vi /etc/hosts修改 hosts文件,在 hosts中 将 jco.server.gwhost:gmdev01  属性值  gmdev01 加入 SAP服务器IP 地址映射10.86.95.121       gmdev012.执行 vi /etc/services修改 services文件,在services文件尾部 将  jco.server.gwserv:sapgw00 属性值 sapgw00 加入 SAP 端口映射sapdp00  3200/tcp #SAP Serversapgw00  3300/tcp #SAP Gateway

linux 下运行

运行
nohup java -jar test.jar >test.txt &
nohup java -XX:-UseGCOverheadLimit -jar test.jar >SYNC_$(date +%Y%m%d%H%M%S).txt &
查找进程
ps -aux|grep test
结束进程
kill -s 9 “pid”

SAP

JCo3.0是Java语言与ABAP语言双向通讯的中间件。与之前1.0/2.0相比,是重新设计的产品。API和架构设计与NCo3.0比较类似,前面也说过,NCo3.0的设计参考了JCo3.0。从本篇开始,系统介绍JCo3.0编程的技术要点。

JCo3.0 安装

下载JCo3.0,注意下载的时候根据操作系统和JVM版本(32位还是64)选择不同的版本。安装就是解压,将文件解压到目标文件夹。以Windows系统为例,主要的文件包括:

sapjco3.dll
sapjco3.jar

SAP强烈推荐将这两个文件放在同一文件夹下。
测试安装是否成功,可以在命令窗口下,进入安装文件夹,运行下面的命令:
java -jar sapjco3.jar

JCoDestination

JCoDestination代表后台SAP系统,程序员不用关心与SAP的连接,jco3.0运行时环境负责管理连接和释放连接。我们先以一个简单的例子看看jco3.0 JCoDestination类的一些要点。

我使用的编程环境是Eclipse,环境准备如下:

  1. 新建一个spring boot项目,项目名为JCo3Demo。

  2. 将sapjco3.jar加入到项目的resources下lib(新建)中。注意前面所说的sapjco3.jar和sapjco3.dll(不需要build path)要放在同一个文件夹下。

  3. 创建实体类SapConn用来存储对接的SAP系统的连接参数,代码如下:

     // SAP服务器private String JCO_ASHOST;// SAP系统编号private String JCO_SYSNR;// SAP集团private String JCO_CLIENT;// SAP用户名private String JCO_USER;// SAP密码private String JCO_PASSWD;// SAP登录语言private String JCO_LANG;// 最大连接数private String JCO_POOL_CAPACITY;// 最大连接线程private String JCO_PEAK_LIMIT;// SAP ROUTERprivate 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;}@Overridepublic 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 + '\'' +'}';}
    
  4. 获取 JCoDestination 的工具类,通过new SAPConnUtils().jCoDestination创建链接并获取JCoDestination类,并且项目根目录下会生成配置文件ABAP_AS_WITH_POOL.jcoDestination

    private static final String ABAP_AS_POOLED = “ABAP_AS_WITH_POOL”;
    public JCoDestination jCoDestination;

    public SAPConnUtils(){
    SapConn con = new SapConn(
    “xxxxx”,
    “00”,
    “300”,
    “xxx”,
    “xxxxx”,
    “zh”,
    “30”,
    “150”,
    “xxxxxxxxx”
    );
    jCoDestination = connect(con);
    }

    /**

    • 创建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){
      System.out.println("Create Data file fault, error msg: " + e.toString());
      throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
      }
      }

    /**

    • 初始化SAP连接
      */

    private static void initProperties(SapConn sapConn) {
    Properties connectProperties = new Properties();
    // SAP服务器
    connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, sapConn.getJCO_ASHOST());
    // SAP系统编号
    connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, sapConn.getJCO_SYSNR());
    // SAP集团
    connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, sapConn.getJCO_CLIENT());
    // SAP用户名
    connectProperties.setProperty(DestinationDataProvider.JCO_USER, sapConn.getJCO_USER());
    // SAP密码
    connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, sapConn.getJCO_PASSWD());
    // SAP登录语言
    connectProperties.setProperty(DestinationDataProvider.JCO_LANG, sapConn.getJCO_LANG());
    // 最大连接数
    connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, sapConn.getJCO_POOL_CAPACITY());
    // 最大连接线程
    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);
    

    }

    /**

    • 获取SAP连接
    • @return SAP连接对象
      */
      public static JCoDestination connect(SapConn sapConn){
      System.out.println(“正在连接至SAP…”);
      JCoDestination destination = null;
      initProperties(sapConn);
      try {
      destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
      destination.ping();
      System.out.println(“已成功建立sap的连接”);
      } catch (JCoException e) {
      System.out.println("Connect SAP fault, error msg: " + e.toString());
      }
      return destination;
      }

}

JCo3.0调用SAP函数的过程

大致可以总结为以下步骤:

  • 连接至SAP系统(参考上面3和4步骤)
  • 创建JcoFunction接口的实例(这个实例代表SAP系统中相关函数)
  • 设置importing参数
  • 调用函数
  • 从exporting参数或者table参数获取数据

JCoFunction接口说明

  • JCoFunction是一个接口,代表SAP系统的函数

  • JCoFunction包含importing参数,exporting参数,changing参数,table参数。分别使用getImportParameterList方法,getExportParameterList方法,getChangingParameterList方法和getTableParameterList获得。这些方法的返回值都是JCoParameter类型

  • JCoFunction.execute方法实际执行函数

如何创建JCoFunction对象

  • 上面的代码是第一种创建JCoFunction实例的方法,BAPI_COMPANYCODE_GETDETAIL为调用函数名:
 JCoRepository repository = dest.getRepository();    JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");
  • 如果我们不关心JCoRepository,也可以这样写:
 JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");
  • 第三种方法是使用JCoFunctionTemplate.getFunction方法,JCoFunctionTemplate也是一个接口,代表SAP函数的meta-data。
  JCoFunctionTemplate fmTemplate= dest.getRepository().getFunctionTemplate("BAPI_COMPANYCODE_GETDETAIL");JCoFunction fm = fmTemplate.getFunction();

设置importing参数

         //调用function函数function = jCoDestination.getRepository().getFunction("调用函数名");//ParamKey为的参数名,以逗号隔开,ParamValue为参数名对应的参数值,if("".equals(ParamKey) || "".equals(ParamValue)) {// 不需要参数}else{String[] paramKeys = ParamKey.split(",");String[] paramValues = ParamValue.split(",");for (int i = 0; i < paramKeys.length; i++) {function.getImportParameterList().setValue(paramKeys[i],"null".equals(paramValues[i]) ? "" : paramValues[i]);}}function.execute(jCoDestination);//提交

设置exporting参数,获取结果

Integer retCode=function.getExportParameterList().getInt("RET_CODE");

设置table参数

Table参数作为export parameter

JCo中,与表参数相关的两个接口是JCoTable和JCoRecordMetaDta, JCoTable就是RFM中tabl参数,而JCoRecordMetaDta是JCoTable或JCoStructure的元数据。
//ET_LOG为table名
JCoTable jcoTable=function.getTableParameterList().getTable(“表名”);
//要点说明:对JCoTable,输出表头和行项目。
//表头通过获取JCoTable的JCoRecordMetaData,然后使用JCoRecordMetaData的getName()方法
JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();
for(int i = 0; i < tableMeta.getFieldCount(); i++){
System.out.print(String.format("%s\t", tableMeta.getName(i)));
}
System.out.println(); // new line
//获取表体
//JCoTable每一行都是一个JCoStructure,可以通过setRow()设置指针的位置,然后再遍历各个field:
for(int i = 0; i < jcoTable.getNumRows(); i++){
// Sets the row pointer to the specified position(beginning from zero)
jcoTable.setRow(i);//每次一张表

           // Each line is of type JCoStructurefor(JCoField fld : jcoTable){System.out.println(String.format("%s\t%s",fld.getName(),fld.getString()));}System.out.println();}

Table参数作为import parameter

table作为输入参数,主要解决填充table的问题,基本模式如下:
someTable.appendRow();
someTable.setValue("FLDNAME", someValue);
以RFC_READ_TABLE为例,读取表.
/**
* Shows how to process JCoTable (as importing)
*/
JCoFunction fm = dest.getRepository().getFunction(“RFC_READ_TABLE”);

    // table we want to query is USR04// which is user authorization table in SAPfm.getImportParameterList().setValue("QUERY_TABLE", "USR04");// output data will be delimited by commafm.getImportParameterList().setValue("DELIMITER", ",");// processing table parametersJCoTable options = fm.getTableParameterList().getTable("OPTIONS");// modification date >= 2012.01.01 and <= 2015.12.31options.appendRow();options.setValue("TEXT", "MODDA GE '20120101' ");options.appendRow();options.setValue("TEXT", "AND MODDA LE '20151231' ");// We only care about fields of [user id] and [modification date]        String[] outputFields = new String[] {"BNAME", "MODDA"};JCoTable fields = fm.getTableParameterList().getTable("FIELDS");int count = outputFields.length;fields.appendRows(count);for (int i = 0; i < count; i++){fields.setRow(i);fields.setValue("FIELDNAME", outputFields[i]);            }fm.execute(dest);JCoTable data = fm.getTableParameterList().getTable("DATA");return data;
在代码中我们使用了两种方法来插入table的行项目,第一种方法:
JCoTable options = fm.getTableParameterList().getTable("OPTIONS");
// modification date >= 2012.01.01 and <= 2015.12.31
options.appendRow();
options.setValue("TEXT", "MODDA GE '20120101' ");
options.appendRow();
options.setValue("TEXT", "AND MODDA LE '20151231' ");

第二种方法:

String[] outputFields = new String[] {"BNAME", "MODDA"};
JCoTable fields = fm.getTableParameterList().getTable("FIELDS");
int count = outputFields.length;
fields.appendRows(count);
for (int i = 0; i < count; i++){fields.setRow(i);fields.setValue("FIELDNAME", outputFields[i]);
}

JCoTable重要方法总结

sapjco3 开发与部署环境设置(以下没验证,网上资料)

链接

windows 环境设置

1. sapjco3.dll 需要与 sapjco3.jar 在同一目录
2. 设置系统环境变量,将sapjco3所在目录加入系统环境变量
3. 根据自己的操作系统版本选择对应的sapjco3包

32位系统

例如:
新建环境变量
变量名: JAVA_SAPJCO
变量值: E:\sapjco3\sapjco3-win32
将新建的 JAVA_SAPJCO 环境变量加入 系统环境变量 Path变量集合中.
%JAVA_SAPJCO%\sapjco3.jar

项目部署运行

32位系统 将 sapjco3.dll 加入到c:/windows/system32/目录 或者 将 sapjco3.dll 加入到 JDK/bin 目录下
64位系统将 sapjco3.dll 加入到c:/windows/SysWOW64/目录 或者 将 sapjco3.dll 加入到 JDK/bin 目录下

部署异常问题

1.问题
异常信息 Can’t load IA 64-bit .dll on a AMD 64-bit platform
项目编译及运行,根据自己的操作系统版本选择对应的sapjco3包
2.问题
报错 java.lang.UnsatisfiedLinkError: no sapjco3 in java.library.path ,
是因为没有找到 sapjco3.dll这个库的路径,安装了JDK的环境中,这个库默认的位置不是在system32下,而是在 JDK/JRE/BIN下面。

sapjco3 开发环境设置

1.开发中需要将sapjco3.jar加入到项目的build path中
2.或者将其加入 本地 maven 库

mvn install:install-file -DgroupId=org.hibersap -DartifactId=sapjco3 -Dversion=3.0 -Dpackaging=jar -Dfile=E:/sapjco3/sapjco3-win32/sapjco3.jar

用以替换 org.hibersap 加载项下载的文件

<dependency><groupId>org.hibersap</groupId><artifactId>sapjco3</artifactId><version>3.0</version>
</dependency>

Linux环境设置

Linux java 环境设置

1.创建目录

mkdir /usr/java

2.把下载的rpm文件copy过去

cp jdk-8u161-linux-x64.rpm /usr/java/

3.进入目录

cd /usr/java

4.添加可执行权限

chmod +x jdk-8u161-linux-x64.rpm

5.执行rpm命令安装

rpm -ivh jdk-8u161-linux-x64.rpm

6.查看是否安装成功

java -version

Linux sapjco3 环境设置

1.解压 sapjco3-linux64 或 sapjco3-linuxintel-3.0.5 当前生产环境 centos_X64_32 系统使用的是 sapjco3-linux64
2.将sapjco3.jar 文件复制至 $JAVA_HOME/lib/sapjco3.jar
3.将 libsapjco3.so 文件复制至 $JAVA_HOME/jre/lib/amd64/server/libsapjco3.so
4.设置环境变量

    vim /etc/profile //修改文件
 JAVA_HOME=/usr/local/javaPATH=$PATH:$JAVA_HOME/binCLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/sapjco3.jarJRE_HOME=$JAVA_HOME/jreLD_LIBRARY_PATH=dir:$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/amd64/serverexport JAVA_HOME LD_LIBRARY_PATH PATH

5.刷新配置
source /etc/profile
6.配置本地 hosts 将主机名字映射到IP地址
1.控制台执行 hostname 命令查看计算机名
2.控制台执行 hostname -i 查看本机IP
3.编辑hosts文件 vi /etc/hosts
4.在 /etc/hosts中 加入
192.168.1.10(本机IP) localhost hostname(计算机名)

建立 Jco Serever 监听服务时相关设置windows jco 监听设置

进入 %SystemRoot%\System32\drivers\etc
1.修改 services文件,在services文件尾部 将  jco.server.gwserv:sapgw00 属性值 sapgw00 加入 SAP 端口映射sapdp00  3200/tcp #SAP Serversapgw00  3300/tcp #SAP Gateway
2.修改 hosts文件,在 hosts中 将 jco.server.gwhost:gmdev01  属性值  gmdev01 加入 SAP服务器IP 地址映射10.86.95.121       gmdev01
3.具体示例参考项目目录内的 services/hosts 文件

linux jco 监听设置

 1.执行  vi /etc/hosts修改 hosts文件,在 hosts中 将 jco.server.gwhost:gmdev01  属性值  gmdev01 加入 SAP服务器IP 地址映射10.86.95.121       gmdev012.执行 vi /etc/services修改 services文件,在services文件尾部 将  jco.server.gwserv:sapgw00 属性值 sapgw00 加入 SAP 端口映射sapdp00  3200/tcp #SAP Serversapgw00  3300/tcp #SAP Gateway

linux 下运行

运行
nohup java -jar test.jar >test.txt &
nohup java -XX:-UseGCOverheadLimit -jar test.jar >SYNC_$(date +%Y%m%d%H%M%S).txt &
查找进程
ps -aux|grep test
结束进程
kill -s 9 “pid”

JAVA对接SAP接口使用sapjco3的见解相关推荐

  1. 2021.12.9 java代码对接sap接口(soap协议、webservice)

    2021.12.9 java对接sap接口(soap协议.webservice) 问题:对接sap接口,代码调试 执行: 1.soapui 软件测试是否能正确访问 未能正确访问,因为未在本地配置域名映 ...

  2. springboot 对接sap接口,不生成连接配置文件文件的方法。

    springboot 对接sap接口,不生成连接配置文件文件的方法. 网上大部分都是要生成两个连接文件,导致部署的时候,要考虑jar和文件怎么部署,很不方便.本文只记录,不生成连接文件这一种方式. 1 ...

  3. JAVA对接短信通知接口

    JAVA对接验证码短信接口DEMO示例 本文为您提供了JAVA语言版本的验证码短信接口对接DEMO示例 新用户注册·验证码短信.语音解决方案 * 接口类型:触发短信接口,支持发送验证码短信.订单通知短 ...

  4. JAVA调用SAP接口地址_Java以webservice方式调用SAP接口传输数据

    Java以webservice方式调用SAP接口传输数据,在SAP中生成 会计凭证/冲销会计凭证 1.生成会计凭证(已完成) 2.冲销会计凭证(以下教程截图以该接口为例) Java调用sap的webs ...

  5. Java对接SAP平台接口

    稍后更新... 转载于:https://www.cnblogs.com/mxh-java/p/11395698.html

  6. java对接第三方接口

    1.准备与第三方接口对接的账号 配置到了Apollo上面 @Value("${taofake.appId}")private String appId;@Value("$ ...

  7. java调用sap接口_(二)通过JAVA调用SAP接口 (增加一二级参数)

    /*** Created by gang.xu01@hand-china.com on 2018/12/4*/ public classMultiFromSAP {/*** description: ...

  8. java 对接第三方接口

    感想 这是我第一次要写对外的接口,一开始还是比较迷茫的,因为要考虑到数据的安全传输,很多技术我都还是比较的不熟悉,后来经过对每一个技术的了解,终于还是写出来了. 感觉一切都是从陌生到熟悉,再到亲切 哈 ...

  9. java获取sap接口数据

    一.方式一接口数据读取及返回值 public class SapConnect {static final String ABAP_AS_POOLED = "ABAP5_WITHOUT_PO ...

  10. java 对接webapi接口数据提交方式之 application/x-www-form-urlencoded

    Content-Type: application/x-www-form-urlencoded;charset=utf-8  这应该是最常见的 POST 提交数据的方式了.浏览器的原生 form 表单 ...

最新文章

  1. 住酒店套房的注意事项
  2. Vue中的箭头函数=>目的是用来简化函数的写法的分为三部分:被赋值的变量 传入的参数 返回的数据
  3. maven打包项目的时候找不到jar包,但是项目里面改已经有相关jar包
  4. 漫谈软件研发特种部队之中的一个
  5. 大物知识点复习框架——振动
  6. java 错误码设计_关于Java中异常的设计
  7. ubuntu之路——day9.2 Covariate shift问题和Batch Norm的解决方案
  8. 2.mongoDB 命令
  9. java线程系列一:Thread类中的start()方法与run方法
  10. 支付宝支付即时到账接口在ThinkPHP商城中的应用
  11. 分享:Tuts4you社区,脱壳教程全集.1.5G
  12. Docker安装Yapi
  13. html暴风粒子代码,魔兽世界课物品代码及gm指令大全(全部整理自网上).doc
  14. 【数学模型】基于Volterra理论的捕食模型
  15. 基于cocos2d-x引擎的游戏框架设计【转载】
  16. 用Python提取图片主要颜色
  17. android+客户端+教程,Android新浪客户端开发教程完整版.pdf
  18. 缓存(cache、Redis)
  19. 微信小程序获取数据接口动态渲染Echarts折线图
  20. yii2框架-yii2的组件和服务定位器(四)

热门文章

  1. WinCE下Touch Panel驱动介绍 .
  2. delphi与python_python和delphi哪个好
  3. 如何使用Protel99 se给PCB文件添加汉字和图形?
  4. VC编程读取文本数据
  5. 测试电池损耗的软件运行原理,鲁大师电池损耗检测准确?鲁大师电池损耗检测原理解析...
  6. matlab前馈仿真,前馈-反馈控制系统的具体分析及其MATLAB/Simulink.PDF
  7. 新版电力系统决策支持系统开发告一段落
  8. 备战数学建模10-主成分分析模型与因子分析模型
  9. html5游戏开发教程实战:五子棋、四子棋、围棋、翻转棋四种对弈游戏,仅仅100行代码
  10. Java编程必备软件