JAVA对接SAP接口使用sapjco3的见解
参考了作者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,环境准备如下:
新建一个spring boot项目,项目名为JCo3Demo。
将sapjco3.jar加入到项目的resources下lib(新建)中。注意前面所说的sapjco3.jar和sapjco3.dll(不需要build path)要放在同一个文件夹下。
创建实体类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 + '\'' +'}';}
获取 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,环境准备如下:
新建一个spring boot项目,项目名为JCo3Demo。
将sapjco3.jar加入到项目的resources下lib(新建)中。注意前面所说的sapjco3.jar和sapjco3.dll(不需要build path)要放在同一个文件夹下。
创建实体类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 + '\'' +'}';}
获取 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的见解相关推荐
- 2021.12.9 java代码对接sap接口(soap协议、webservice)
2021.12.9 java对接sap接口(soap协议.webservice) 问题:对接sap接口,代码调试 执行: 1.soapui 软件测试是否能正确访问 未能正确访问,因为未在本地配置域名映 ...
- springboot 对接sap接口,不生成连接配置文件文件的方法。
springboot 对接sap接口,不生成连接配置文件文件的方法. 网上大部分都是要生成两个连接文件,导致部署的时候,要考虑jar和文件怎么部署,很不方便.本文只记录,不生成连接文件这一种方式. 1 ...
- JAVA对接短信通知接口
JAVA对接验证码短信接口DEMO示例 本文为您提供了JAVA语言版本的验证码短信接口对接DEMO示例 新用户注册·验证码短信.语音解决方案 * 接口类型:触发短信接口,支持发送验证码短信.订单通知短 ...
- JAVA调用SAP接口地址_Java以webservice方式调用SAP接口传输数据
Java以webservice方式调用SAP接口传输数据,在SAP中生成 会计凭证/冲销会计凭证 1.生成会计凭证(已完成) 2.冲销会计凭证(以下教程截图以该接口为例) Java调用sap的webs ...
- Java对接SAP平台接口
稍后更新... 转载于:https://www.cnblogs.com/mxh-java/p/11395698.html
- java对接第三方接口
1.准备与第三方接口对接的账号 配置到了Apollo上面 @Value("${taofake.appId}")private String appId;@Value("$ ...
- java调用sap接口_(二)通过JAVA调用SAP接口 (增加一二级参数)
/*** Created by gang.xu01@hand-china.com on 2018/12/4*/ public classMultiFromSAP {/*** description: ...
- java 对接第三方接口
感想 这是我第一次要写对外的接口,一开始还是比较迷茫的,因为要考虑到数据的安全传输,很多技术我都还是比较的不熟悉,后来经过对每一个技术的了解,终于还是写出来了. 感觉一切都是从陌生到熟悉,再到亲切 哈 ...
- java获取sap接口数据
一.方式一接口数据读取及返回值 public class SapConnect {static final String ABAP_AS_POOLED = "ABAP5_WITHOUT_PO ...
- java 对接webapi接口数据提交方式之 application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded;charset=utf-8 这应该是最常见的 POST 提交数据的方式了.浏览器的原生 form 表单 ...
最新文章
- 住酒店套房的注意事项
- Vue中的箭头函数=>目的是用来简化函数的写法的分为三部分:被赋值的变量 传入的参数 返回的数据
- maven打包项目的时候找不到jar包,但是项目里面改已经有相关jar包
- 漫谈软件研发特种部队之中的一个
- 大物知识点复习框架——振动
- java 错误码设计_关于Java中异常的设计
- ubuntu之路——day9.2 Covariate shift问题和Batch Norm的解决方案
- 2.mongoDB 命令
- java线程系列一:Thread类中的start()方法与run方法
- 支付宝支付即时到账接口在ThinkPHP商城中的应用
- 分享:Tuts4you社区,脱壳教程全集.1.5G
- Docker安装Yapi
- html暴风粒子代码,魔兽世界课物品代码及gm指令大全(全部整理自网上).doc
- 【数学模型】基于Volterra理论的捕食模型
- 基于cocos2d-x引擎的游戏框架设计【转载】
- 用Python提取图片主要颜色
- android+客户端+教程,Android新浪客户端开发教程完整版.pdf
- 缓存(cache、Redis)
- 微信小程序获取数据接口动态渲染Echarts折线图
- yii2框架-yii2的组件和服务定位器(四)
热门文章
- WinCE下Touch Panel驱动介绍 .
- delphi与python_python和delphi哪个好
- 如何使用Protel99 se给PCB文件添加汉字和图形?
- VC编程读取文本数据
- 测试电池损耗的软件运行原理,鲁大师电池损耗检测准确?鲁大师电池损耗检测原理解析...
- matlab前馈仿真,前馈-反馈控制系统的具体分析及其MATLAB/Simulink.PDF
- 新版电力系统决策支持系统开发告一段落
- 备战数学建模10-主成分分析模型与因子分析模型
- html5游戏开发教程实战:五子棋、四子棋、围棋、翻转棋四种对弈游戏,仅仅100行代码
- Java编程必备软件