一、JCO接口介绍

       JCO采用的是中间式接口,即外部系统将SAP系统所需的信息生成中间数据表,SAP系统直接读取中间文件或将中间表中的信息写入数据库中,中间式接口是比较常用的一种方式,这种方式外部系统和SAP系统相对独立,接口不涉及双方内部的结构,而且接口的责任也很明确,数据的安全性也得到了保证。但这种方式存在的问题就是两个系统的数据同步性稍差一些,但只要合理地规定读写中间文件或数据表的时间,数据的同步性是不会影响使用的。

二、JCO接口开发流程介绍

  1. 配置A系统和SAP系统的连接,建立两个系统的连接
  2. A系统获取需要调用SAP系统的方法,如ZBAPI_HAHA
  3. A系统传参数给方法
  4. 连接对象执行这个方法
  5. 获得返回的结果
  6. 释放连接

三、基于SpringBoot技术实际项目开发

  1、配置A系统和SAP系统的连接,建立两个系统的连接,其中连接有两种连接

      1)第一种连接配置

               1.根据操作系统将sapjco3.dll文件放入C:\Windows\System32目录;

               2.在项目中引入sapjco3.jar包;

               3.创建DisplaySalesActivity.java类,配置生成连接

public class DisplaySalesActivity {
    static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL";
    static String DESTINATION_NAME2 = "ABAP_AS_WITH_POOL";
    //配置连接
    static {
        Properties connectProperties = new Properties();
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "127.0.0.1");//IP
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");//系统编号
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "001");//客户端编号
        connectProperties.setProperty(DestinationDataProvider.JCO_USER, "username");//用户名
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password");//密码
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "zh");//语言
        createDestinationDataFile(DESTINATION_NAME1, connectProperties);
        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "30");//最大空闲连接数
        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "150");//最大活动连接数
        createDestinationDataFile(DESTINATION_NAME2, connectProperties);
    }
    /*
    *创建配置连接文件
    /
    static void createDestinationDataFile(String destinationName, Properties connectProperties) {
        File destCfg = new File(destinationName + ".jcoDestination");
        try {
            FileOutputStream fos = new FileOutputStream(destCfg, false);
            connectProperties.store(fos, "For tests only !");
            fos.close();
        } catch (Exception e) {
            throw new RuntimeException("Unable to create the destination files", e);
        }
    }

    /*
    *获取连接
    /
    public static JCoDestination getSAPDestination() throws JCoException {
        JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME2);

        return destination;

    }

    public static void main(String[] args) throws JCoException {
        getSAPDestination();
    }

配置好后运行main方法,生成2个连接配置文件(DESTINATION_NAME1 与DESTINATION_NAME2 )和2个日志文件,如果

在Tomcat中运行,配置好生成地址可以直接在应用中调连接方法。

(2)第二种连接配置(建议使用这种连接)

       1.配置环境: 
下载sapjco3.dll、librfc32.dll、sapjcorfc.dll放至C:\Windows\System32目录,缺一不可;
下载sapjco3.jar置放工程中,jar包可通过依赖导入或者直接下载。

这里分享一下sapjco3相关文件百度网盘,暂只供本机我自己的电脑(windows7系统,64bit)可用,如无法使用请重新去下载使用。

链接:https://pan.baidu.com/s/11kzlleiHqrkEuAu29ULEoA 
提取码:lz0z 
(包含sapjco3.dll、librfc32.dll、sapjcorfc.dll、sapjco3.jar)

这里温馨提醒一下,上面4个文件都是必须要配置成功的,不然会无法进行连接,出现一些连接问题。

如我遇到的几个问题:

JCO.nativeInit(): Could not initialize dynamic link library librfc. Found version "640.0.144" but required at least version "640.0.377".] with root cause

      2.配置访问属性文件 
SAPConnectionPool.properties

jco.client.lang=zh #语言 
jco.destination.peak_limit=150 #最大活动连接数 
jco.client.client=001 #客户端编号 
jco.client.passwd=password #密码 
jco.client.user=username #用户名 
jco.client.sysnr=00 #系统编号 
jco.destination.pool_capacity=30 #最大空闲连接数 
jco.client.ashost=127.0.0.1 #IP

2、封装获取链接池链接Java类,以便接口使用时调用





import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.Client;
import com.sap.mw.jco.JCO.Function;
import com.sap.mw.jco.JCO.Repository;
import com.sap.mw.jco.JCO.Table;

import ep.dhcsoft.java.OrderedProperties;

public class SAPConn {
	private static final String POOL_NAME = "Pool";
	//这里value为空的字段,暂时没看到哪里用到过
    private static String clientNum = ""; //客户端编号
    private static String userName = ""; //用户名
    private static String password = ""; //密码
    private static String hostname = ""; //
    private static String systemnumber = ""; //系统编号
    private static String Language = "";
    private static com.sap.mw.jco.JCO.Pool pool = null;
    private static int maxconn = 120; //最大连接数
    private static String sources = "";
    private static Log log = LogFactory.getLog(SAPConn.class);
    
	public  Client getSAPPoolConnection() {
    	JCO.Client mConn = null;
        try
        {
            log.info("-------------SAP Client Connects Start ----------------");
            Properties props = new Properties();  
            InputStream in = SAPConn.class.getResourceAsStream("/SAPConnectionPool.properties");
            props.load(in);
            pool = JCO.getClientPoolManager().getPool(POOL_NAME);//这里有异常,这里pool为null
            if(pool == null){
                JCO.addClientPool(POOL_NAME, maxconn,props);//这里重新去获取
            }
            mConn = JCO.getClient(POOL_NAME);
            log.info("get connection success");
        }
        catch(Exception exception)
        {
            log.info((new StringBuilder()).append("get connection error:").append(exception).toString());
        } 
        return mConn;
    }

    public  void releaseC(JCO.Client client){ //释放连接
        if(client != null)
        {
            JCO.releaseClient(client);
        }
    }
    
    //获取 sap bapi 方法
    public Function excuteBapi(String s,Client mConn)
    {
    	Function function = null;
		try {
			 JCO.Repository mRepository;
			 mRepository = new JCO.Repository("ARAsoft", mConn);  
			 IFunctionTemplate ft = mRepository.getFunctionTemplate(s);
			 function = ft.getFunction();
		} catch (Exception localException) {
			localException.printStackTrace();
	        log.error(localException);
		} 
		return function;
    }
    
    
	/**
	 * 获取结果集 封装在map 中 ,键值为rslist
	 * @param solist
	 * @return
	 */
	public  static Map getSuccessMap(Table solist) {
		Map<String, Object> retMap = new HashMap<String, Object>();
		List rslist = new ArrayList();
		if (solist.getNumRows() > 0) {
			do {
				Map<String,String> tempmap = new HashMap();
				for (JCO.FieldIterator fI = solist.fields(); fI
						.hasMoreElements();) {
					JCO.Field tabField = fI.nextField();
					tempmap.put(tabField.getName(), tabField.getString());
				}
				rslist.add(tempmap);
			} while (solist.nextRow() == true);
		}

		retMap.put("result", rslist);
		retMap.put("success", "true");
		return retMap;
	}
	
	
}




3、建立的连接demo

   1、controller请求

 /**
     * 通过接口获得数据
     * */
    @RequestMapping(value = "/querySettlementCurrency")
    @ResponseBody
    public Map<String, Object> querySettlementCurrency(AccountInfo record,QueryParams qps,HttpSession session, HttpServletRequest request, HttpServletResponse response) {
    	Map<String, Object> result = new HashMap<String, Object>();
    	SettlementCurrency settlementCurrency = new SettlementCurrency();
		result=settlementCurrency.getSettlementCurrency();
		System.out.println("result:"+result);
        return result;
    }

   2、SettlementCurrency连接demo



import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;


import com.sap.conn.jco.JCoStructure;
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.ParameterList;
import com.sap.mw.jco.JCO.Structure;
import com.sap.mw.jco.JCO.Table;

import ep.dhcsoft.java.OrderedProperties;

/*
 * 弹窗出现数组接口
 * 
 * */
public class SettlementCurrency {
	static final String POOL_NAME = "Pool";
	public Map<String, Object>  getSettlementCurrency()  {
 		JCO.Client mConn = null;
		Map<String, Object> resultMap = new HashMap<>();
		SAPConn sapConn = new SAPConn();
		 try {
			  	mConn = sapConn.getSAPPoolConnection();//这里有异常,无法获得连接
		        JCO.Function function = sapConn.excuteBapi("AAA",mConn);
		        
				//执行接口
		        mConn.execute(function);
				//接口返回结果
		        
		        JCO.Table returnStructure =  function.getTableParameterList().getTable("Return");
			  resultMap= SAPConn.getSuccessMap(returnStructure);
		      JCO.releaseClient(mConn);/*deprecated是表示这是个过时的方法,将来会被取消的,现在有主要是为了老代码的兼容;*/
		 }catch(Exception exception){
	          System.out.println(exception.getMessage());
	      } finally{
	    	  sapConn.releaseC(mConn); //释放连接
	      }
      return resultMap;  //返回从SAP获取的结果。
	}
}

参考文章:JAVA使用JCO实现调用SAP接口方法_默默同学的BLOG-CSDN博客_jco接口

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐