Java 使用 JCO3 实现调用 SAP 接口小结

Java 可以使用 JCO3 包提供的方法调用 SAP 的接口,为了能够访问 SAP 系统,首先必须对相关参数进行配置。

一、 配置连接

1、 将 sapjco3.dll 动态链接库文件放入 C:\Windows\System32 目录中。 

2、 在项目中引入 sapjco3.jar 包。在 eclipse 中可以在 src\main\webapp\WEB-INF 目录下,新建一个 lib 目录,将 sapjco3.jar 放入该目录中,然后右键点击项目,选择 Build Path→Configure Build Path→Add Library→Web App Libraries→Next→Finish。

3、 配置 SAP 系统的连接参数,并生成连接配置文件,代码如下所示。

import java.io.File;

import java.io.FileOutputStream;

import java.util.Properties; 

import com.sap.conn.jco.JCoStructure;

import com.sap.conn.jco.JCoTable;

import com.sap.conn.jco.JCoFunction;

import com.sap.conn.jco.JCoException;

import com.sap.conn.jco.ext.DestinationDataProvider;

import com.sap.conn.jco.JCoDestination;

import com.sap.conn.jco.JCoDestinationManager;

public class SapUtil{

 static String ABAP_AS_POOLED = “ABAP_AS_WITH_POOL”; 

static
{
 Properties connectProperties = new Properties();

 connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, “192.168.2.24”); //SAP 服务器地址
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR ,“00”); // 服务器编号

 connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, “300”); // 登录集团编号

 connectProperties.setProperty(DestinationDataProvider.JCO_USER,“XXXX”); // 登录用户名

 connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, “123456”); // 密码

 connectProperties.setProperty(DestinationDataProvider.JCO_LANG, “ZH”); // 默认语言中文    

 connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT ,“10”); // 最大活动连接数  

 connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY,“1”); // 最大空闲连接数     

createDataFile(ABAP_AS_POOLED, “jcoDestination” ,connectProperties);
 }

在上面的代码中,各个配置项的值都是取的固定值。在我们的实际项目中,可以使用自定义项档案,在自定义项档案中定义 SAP 的连接参数,然后在程序中读取配置项的值,如下所示。

// 查询登录用户名
String hql4 = “from MbbUdi u where u.isDelete = 0 and u.code = ‘USER’ and u.udiType.isDelete = 0 and u.udiType.code = ‘SAPPZ’”;

List udis4 = this.getDao().findHql(hql4);       

String user = "";

if (udis4 != null && udis4.size() > 0) {

user = udis4.get(0).getRemark();

}       

if (StringUtils.isBlank(user)) {

throw new MestarException(“登录用户名为空,请维护自定义项档案”);

}     

connectProperties.setProperty(DestinationDataProvider.JCO_USER, user); // 登录用户名

需要将属性配置保存成属性文件,该属性文件的后缀名必须为 jcoDestination,Java 通过 JCO3 连接 SAP 系统时需要用到该连接配置文件。

public void createDataFile(String name, String suffix, Properties properites){

// 生成文件名

File cfg = new File(name+“.”+suffix);

// 文件不存在,则创建

if(!cfg.exists()){

try {

FileOutputStream fos = new FileOutputStream(cfg, true); // true 表示追加模式

properites.store(fos, “just for test”);

fos.close();

} catch (Exception e) {

throw new MestarException(e.getMessage());

}     

}   

}

4、 JCO3 程序到当前类所在目录中搜索属性连接配置文件,并根据文件中的配置信息来创建连接。

public JCoDestination getSapDestination() throws JCoException{               

JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);       

return destination;

}

二、 接口调用

1、 通过需要调用的 SAP 系统函数名,得到一个 JCoFunction 对象。

JCoFunction function = destination.getRepository().getFunction(“ZSRM_SS019_MAINLIFNR”);

2、 对得到的 JCoFunction 对象的输入参数赋值,输入参数包括一般参数、结构体参数、表参数。

一般参数可以直接赋值,代码如下所示:

function.getImportParameterList().setValue(“I_VBELN”,vbelnno);

赋值结构体参数需要先获得一个 JCoStructure 对象,然后对 JCoStructure 对象的各个属性赋值,代码如下所示:

// 赋值结构体参数  

JCoStructure i_header = function.getImportParameterList().getStructure(“IS004”);    i_header.setValue(“I_ERSDA_H”,  “2021-11-01”); // 创建结束日期

i_header.setValue(“I_ERSDA_L”, “2021-10-01”); // 创建开始日期

赋值表参数与赋值结构体参数类似,也需要先获得一个 JCoTable 对象,不同的是表参数可以添加多行,代码如下所示:

JCoTable t_import_01 = function.getTableParameterList().getTable(“T_IMPORT_01”);

// 如果为参数集合,在外层加 for 循环即可。

t_import_01.appendRow();

t_import_01.setValue(“MATNR”, “6020001”);

t_import_01.setValue(“KWMENG”, 10);           

在上面的注释处添加 for 循环,可以实现添加多行参数的功能。

3、 通过调用 JCoFunction 对象的 execute 方法,调用 SAP 提供的接口函数,代码如下所示:

function.execute(destination);

4、 获取 SAP 接口的返回结果,返回结果有一般变量和表两种形式。获取一般变量的代码如下所示:

String e_flag = function.getExportParameterList().getString(“E_FLAG”);

获取返回表的代码如下所示:

JCoTable returnStructure = function.getTableParameterList().getTable(“ITME1”);

for (int i = 0; i < returnStructure.getNumRows(); i++) {

returnStructure.setRow(i); 

System.out.println(returnStructure.getString(“MATNR”));

System.out.println(returnStructure.getString(“MAKTX”));

}