java 通过RFC 与 SAP 做交互
公司要开始对接SAP系统,所以对此我们要通过RFC接口往sap抛数据 以及 可能要通过 rfc 拉sap数据。所以代码记录下,以备不时之需。
首先先把环境配置下(其实也就几个文件而已))(这东西百度就能找到)
sapjco3.jar 导入jar包
sapjco3.dll 放 c:/windows/system32
//以上单机环境测试无误,但是在服务器上调用就报错。
sapjco3.dll 在放入 libs文件夹,解决。
片段一:sap 链接配置
package com.test;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
import com.test.LoggerUntil;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
//與sap連接的配置
//呼叫 dev環境的 rfc連接
public class SapDEVConn {
private static final String ABAP_AS_POOLED = "DEV_ECD";//连接池名
static{
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "xxx.xxx.xxx.xx"); //服务器
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "xx"); //系统编号
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx"); //客户端编号
connectProperties.setProperty(DestinationDataProvider.JCO_USER, SapConfig.USER); //账户
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, SapConfig.PASSWD); //密码
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ZF"); //登录语言
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "30"); //最大连接数
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "100"); //最大连接线程
createDataFile(ABAP_AS_POOLED, "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();
}
/*
* Properties类是集合和IO技术结合的成果.可以把数据以Map集合的形式存入,也可以通过IO流技术读取或者输出.
* 该类的store方法,是一个输出方法. store(OutputStream out, String comments)
* 以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。
*/
try{
FileOutputStream fos = new FileOutputStream(cfg, false);
properties.store(fos, "for tests only !");
fos.close();
}catch (Exception e){
LoggerUntil.sap_error_log("DEV_SAP -----> Create Data file fault, error msg: " + e.getMessage(), e);
throw new RuntimeException("DEV_SAP -----> Unable to create the destination file " + cfg.getName(), e);
}
}
/**
* 获取SAP连接
* @return SAP连接对象
*/
public static JCoDestination DEV_connect(){
JCoDestination destination =null;
try {
destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);//获取SAP连接
} catch (JCoException e) {
LoggerUntil.sap_error_log("DEV_SAP -----> Connect SAP fault, error msg: " + e.getMessage(), e);
}
return destination;
}
}
片段二:java 调用 rfc 往 sap 抛数据
package com.xxx.xxx;
import java.util.Date;
import java.util.List;
import com.test.entity.file;
import com.test.LoggerUntil;
import com.test.SapUntil;
import com.test.SapDEVConn;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoTable;
public class SapDeal {
//-------------------
public static String executeParam(List<file> list){
try {
//连接SAP,获取一个连接对象
JCoDestination lj = SapDEVConn.DEV_connect();
//获取到SAP的函数
JCoFunction function = lj.getRepository().getFunction("Z_MM_GOODSMVT");
JCoParameterList imP = function.getImportParameterList();
//利用setValue将input入参参数传入(规定几个传几个setValue)
imP.setValue("I_CLIENT", "00");
//2.传递 migo结构表格的值(这里就开始往sap抛数据进去了)
JCoTable jCoTable_param = function.getTableParameterList().getTable("IT_WOIMIGO");
//System.out.println(jCoTable_param);
//(同理如果你是对象集合的话,循环就行了,单个对象的话,获取第一行。)
for(int i=0;i<list.size();i++){
jCoTable_param.appendRow();
jCoTable_param.setRow(i);
//这里根据你的migo结构表格的参数传
jCoTable_param.setValue("DOC_TYPE",list.get(i).getType());
}
//执行将数据传给sap
function.execute(lj);
//执行结束了,这里开始获取返回的结果table
JCoTable jCoTable_result = function.getTableParameterList().getTable("RETURN");
//System.out.println(jCoTable_result);
//一般结果都是第一行,只是取出第一行就可以了 (随机应变,调试看)
jCoTable_result.setRow(0);
//String type = jCoTable_result.getString("TYPE");
//String message = jCoTable_result.getString("MESSAGE");
System.out.println(type);
System.out.println(message);
String client = "";
String padid = "";
String e_MAT_DOC = "";
String e_DOC_YEAR = "";
if(!type.equals("S")){
LoggerUntil.error_log("--- sap---> result -- : " + type + message,null);
}else{
//成功后,获取所需要的属性参数。
client = function.getExportParameterList().getString(SapCommonUntil.E_CLIENT);
padid = function.getExportParameterList().getString(SapCommonUntil.E_PDAID);
e_MAT_DOC = function.getExportParameterList().getString(SapCommonUntil.E_MAT_DOC);
e_DOC_YEAR = function.getExportParameterList().getString(SapCommonUntil.E_DOC_YEAR);
}
//組裝成返回結果的信息類
} catch (Exception e) {
LoggerUntil.error_log(e.getMessage(), e);
}
return e_MAT_DOC ;
}
//類的括號--------
}
有些可能会需要传递多个结构的,反正只要在function.execute(lj);提交前写就行了。先获取结构table,在根据结构table的参数去赋值,ok。
片段三:java 通过rfc 接收sap 数据
package com.lotes.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.lotes.pda.untilrfc.conn.SapDEVConn;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoRecordMetaData;
import com.sap.conn.jco.JCoTable;
public class SAPtest {
static List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>();
static JCoFunction function;
public static List<Map<String, Object>> RfcTest(String test){
try {
//连接SAP,获取一个连接对象
JCoDestination lj = SapDEVConn.DEV_connect();
//获取到SAP的函数
function = lj.getRepository().getFunction("ZRFC_SD9002");
//该入参没有放在结构表或者表格中,直接使用getImportParameterList方法
JCoParameterList imP = function.getImportParameterList();
//利用setValue将入参参数传入
imP.setValue("S_P0", "2100");
//imP.setValue("S_P1", "4567");
//imP.setValue("S_P2", "8901234567");
//执行将数据传给sap
function.execute(lj);
//获取到该表格的名称 指定table
//JCoTable jCoTable1 = function.getTableParameterList().getTable("IT_LIKP");
// 遍历全部得到的table并处理
for (JCoField field : function.getTableParameterList()) {
// 按照需求可以整理出一条一条的数据以便插入数据库
JCoTable responseTable = field.getTable();
// 获取metaData(包含表的关键信息)
JCoRecordMetaData metaData = responseTable.getRecordMetaData();
Map<String, Object> sapData = new HashMap<String, Object>();
sapData.put("FieldCount", metaData.getFieldCount());
String[] name = new String[Integer.parseInt(sapData.get("FieldCount").toString())];
List<Map<String, String>> sapList = new ArrayList<Map<String, String>>();
// 获取全部名称
for (int j = 0; j < Integer.parseInt(sapData.get("FieldCount").toString()); j++) {
name[j] = metaData.getName(j);
}
sapData.put("FieldNames", name);
// 获取全部数据
System.out.println("###"+responseTable);
for (int i = 0; i < responseTable.getNumRows(); i++) {
responseTable.setRow(i);
Map<String, String> sapMap = new HashMap<String, String>();
for (String fieldName : name) {
sapMap.put(fieldName, responseTable.getString (fieldName));
}
sapList.add(sapMap);
}
sapData.put("Data", sapList);
returnList.add(sapData);
}
} catch (Exception e) {
e.printStackTrace();
}
return returnList;
}
//
// @SuppressWarnings("unchecked")
// public static void main(String[] args) {
// List<Map<String, Object>> list = RfcTest("");
// List<Map<String, String>> sapList = (List<Map<String, String>>) list.get(0).get("Data");
// //for(int i = 0;i<sapList.size();i++){
// //System.out.println(sapList.get(0).keySet()+":====:"+sapList.get(0).values());
// //}
// for(String key:sapList.get(0).keySet()){
// System.out.println("key值:"+key+"====value值:"+sapList.get(0).get(key));
// }
//
// }
}
写个笔记,记录下。