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));
//		}
//
//	}
	
	
}

写个笔记,记录下。