JAVA使用JCo连接SAP
1. SAP Java Connector (SAP JCo) 是JAVA与SAP相互通信的中间件组建,该组建支持双向通讯模式(inbound calls 和 outbound calls )。JCo支持Connection Pools和Direct两种方式的连接。直接连接需要开发者来控制连接的创建和释放,使用连接池方式可以让池来管理连接的分配、管理和释放,可以最大限度的节省系统开销,相比直接方式优势也是明显的。本文将演示的Direct方式的连接。
2. 最新版本的JCo库可以在如下网址https://service.sap.com/connectors下载(请选择适合你的软件和硬件平台的版本,本文的示例都基于64位Windows操作系统),如与博主版本相似,也可以从如下百度云链接链接:(https://pan.baidu.com/s/1EuYcb2It-lnCmesshlmyaA
提取码:me76)下载需要的sapjco3.dll和sapjco3.jar。官方网站下载好ZIP资源包后,将ZIP包解压,如果只是开发Web App(如本文演示),可以选择不安装的,直接把sapjco3.dll和sapjco3.jar放到项目的lib目录中就可以了(dll和jar需放到同级目录)。下面就介绍sap连接配置文件SapConn.jcoDestination,具体配置连接信息根据具体项目修改即可。
jco.client.lang=ZF
jco.client.trace=0
#jco.destination.peak_limit=10
#jco.destination.pool_capacity=3
#jco.client.mshost=//message server
#SAP application server name or IP.(会变)(以后会变)
jco.client.ashost=10.1.0.101
#SAP R3系统标识(会变)
#jco.client.r3name=DEV
#SAP系统编号(会变)
jco.client.sysnr=00
#500是测试环境(会变)(以后会变)
jco.client.client=520
#SAP系统访问用户(会变)
jco.client.user=rfc_test
#SAP系统访问密码(会变)
jco.client.passwd=rfctest
再创建一个SapJCoInterface的类,用来读取配置文件SapConn.jcoDestination 来注册Provider,获取myConnection和repository,代码如下:
import java.io.File;
import java.io.IOException;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoRepository;
/**
* Sap配置文件读取
* @author lenovo
*
*/
public class SapJCoInterface
{
public static JCoDestination myConnection;
private static JCoRepository repository;
public static JCoRepository getRepository() throws JCoException
{
if (repository == null)
{
synchronized (SapJCoInterface.class)
{
if (repository == null)
{
String configFileName = "SapConn";
File configFile = new File(configFileName +".jcoDestination");
if (!configFile.exists())
{
try
{
System.out.println("未找到SAP接口连接配置文件" + configFile.getCanonicalPath());
}
catch (IOException e)
{
e.printStackTrace();
}
}
myConnection = JCoDestinationManager.getDestination(configFileName);
repository = myConnection.getRepository();
}
}
}
return repository;
}
}
3.下面我们将用接口文档+代码调用的形式来讲解常见形式的几种sap接口函数,如下所示:
3.1:无输入参数,输出为表数据(即返回多条查询记录)
代码实现:
JCoFunction function;
try {
function = SapJCoInterface.getRepository().getFunction("ZWMS_GET_MATERIAL_SHORTAGELIST");
function.execute(SapJCoInterface.myConnection);
} catch (JCoException e) {
e.printStackTrace();
throw new WDKException("SapJCoInterface接口连接失败");
}
// 表输出,拿到Table参数列表
JCoTable tblexport = function.getTableParameterList().getTable("IT_SHORTLIST");
System.out.println("数据数量:"+tblexport.getNumRows());
for (int i = 0; i < tblexport.getNumRows(); i++) {
tblexport.setRow(i);
JSONObject joi = new JSONObject();
joi.put("BUDAT", tblexport.getString("BUDAT"));
joi.put("UZEIT", tblexport.getString("UZEIT"));
joi.put("AUFNR", tblexport.getString("AUFNR"));
//其他需要的表字段也通过tblexport.getString(字段名)取值即可
}
3.2:有输入参数,且为等值查询,输出为表数据(即返回多条查询记录)
代码实现:
String p_matnr = "4546346";
JCoFunction function;
try {
function = SapJCoInterface.getRepository().getFunction("ZWMS_GET_MATERIAL_INFO");
//获取输入参数列表
JCoParameterList input = function.getImportParameterList();
//设置输入查询参数
input.setValue("P_MATNR", p_matnr);
function.execute(SapJCoInterface.myConnection);
} catch (JCoException e) {
e.printStackTrace();
throw new WDKException("SapJCoInterface接口连接失败");
}
// 表输出
JCoTable tblexport = function.getTableParameterList().getTable("IT_MATINFO");
System.out.println("数据数量:"+tblexport.getNumRows());
for (int i = 0; i < tblexport.getNumRows(); i++) {
tblexport.setRow(i);
String MATNR = tblexport.getString("MATNR");
System.out.println(MATNR);
String SPECID = tblexport.getString("SPECID");
System.out.println(SPECID);
//其他需要的表字段也通过tblexport.getString(字段名)
}
3.3:有输入参数,且为区间查询,输出为表数据(即返回多条查询记录)
代码如下:
String start_date = "20190101";
String end_date = "20191224";
JCoFunction function;
try {
function = SapJCoInterface.getRepository().getFunction("ZWMS_GET_MATERIAL");
//获取输入参数列表
JCoParameterList input = function.getImportParameterList();
//设置第一个查询参数
JCoTable tbZS_ERDAT = input.getTable("ZS_ERSDA");
tbZS_ERDAT.appendRow();
tbZS_ERDAT.setValue("SIGN", "I");
tbZS_ERDAT.setValue("OPTION", "BT");
tbZS_ERDAT.setValue("LOW", start_date);
tbZS_ERDAT.setValue("HIGH", end_date);
//设置第二个查询参数
JCoTable ZS_WERKS = input.getTable("ZS_MATNR");
ZS_WERKS.appendRow();
ZS_WERKS.setValue("SIGN", "I");
ZS_WERKS.setValue("OPTION", "BT");
ZS_WERKS.setValue("LOW", "001");
ZS_WERKS.setValue("HIGH", "999");
function.execute(SapJCoInterface.myConnection);
} catch (JCoException e) {
e.printStackTrace();
throw new WDKException("SapJCoInterface接口连接失败");
}
// 表输出
JCoTable tblexport = function.getTableParameterList().getTable("IT_MAT");
System.out.println("数据个数:"+tblexport.getNumRows());
for (int i = 0; i < tblexport.getNumRows(); i++) {
tblexport.setRow(i);
String MAKTX = tblexport.getString("MAKTX");
String MATNR = tblexport.getString("MATNR");
String MEINS = tblexport.getString("MEINS");
String LGORT = tblexport.getString("LGORT");
}
3.4:有输入参数,且为表数据输入(即上传多条数据),输出为表数据(对应上传数据的上传结果)
代码实现:
JCoFunction function;
JCoParameterList tablelist;
try {
function = SapJCoInterface.getRepository().getFunction("ZWMS_WO_POST");
//拿到Table参数列表
tablelist = function.getTableParameterList();
// 表输入
JCoTable headerImportParam = tablelist.getTable("IT_WOPOST");
//示例代码中allrows为json数组
for (int i = 0; i < allrows.size(); i++) {
JSONObject joi = allrows.getJSONObject(i);
headerImportParam.appendRow();
headerImportParam.setValue("AUFNR", joi.getString("aufnr"));// 生產訂單號碼
headerImportParam.setValue("GAMNG", joi.getString("gamng"));// 生產訂單數量
}
function.execute(SapJCoInterface.myConnection);
} catch (JCoException e) {
e.printStackTrace();
throw new WDKException("SapJCoInterface接口连接失败");
}
// 表输出
JCoTable tblexport = tablelist.getTable("IT_WOPOSTOT");
for (int i = 0; i < tblexport.getNumRows(); i++) {
tblexport.setRow(i);
String MBLNR = tblexport.getString("MBLNR");
String AUFNR = tblexport.getString("AUFNR");
String GAMNG = tblexport.getString("GAMNG");
String MSG = tblexport.getString("MSG");
System.out.println("物料文件號碼:"+MBLNR);
System.out.println("生產訂單號碼:"+AUFNR);
System.out.println("生產訂單數量:"+GAMNG);
System.out.println("信息提示:"+MSG);
}
3.5:有输入参数,且为表数据输入(即上传多条数据),输出为非表数据的单个字段(意为多条数据的上传是否同时成功)
代码实现:
JCoFunction function;
try {
function = SapJCoInterface.getRepository().getFunction("ZWMS_MATERIAL_STOCK_UPDATE");
JCoParameterList tablelist = function.getTableParameterList();
// 表输入
JCoTable headerImportParam = tablelist.getTable("IT_STOCKPOST");
//allrows为json数组
for (int i = 0; i < allrows.size(); i++) {
JSONObject joi = allrows.getJSONObject(i);
headerImportParam.appendRow();
headerImportParam.setValue("MATNR", joi.getString("matnr"));// 物料號碼
headerImportParam.setValue("WERKS", joi.getString("werks"));// 工廠
headerImportParam.setValue("LGORT", joi.getString("lgort"));// 儲存地點
headerImportParam.setValue("Z_LABST", joi.getString("z_labst"));// 盤點數量
headerImportParam.setValue("LABST", joi.getString("labst"));// 庫存數量
headerImportParam.setValue("Z_SUB", joi.getString("z_sub"));// 差異數量:差異數量=盤點數量-庫存數量
}
function.execute(SapJCoInterface.myConnection);
} catch (JCoException e) {
e.printStackTrace();
throw new WDKException("SapJCoInterface接口连接失败");
}
//获取输出结果参数
JCoParameterList result = function.getExportParameterList();
// 信息提示
String msgtxt = result.getString("MSGTXT");
// 操作结果
String mtype = result.getString("MTYPE");
System.out.println("盘点结果上传信息:"+msgtxt);
//S为成功
System.out.println("盘点结果上传编码:"+mtype);
4.以上各种输入输出参数形式可以混合使用,具体根据实际项目接口修改,欢迎有问题的小伙伴交流~
上一篇: 印度人一笑而过