关于python 连接 SAP rfc接口的新思路 - Go语言中文社区

关于python 连接 SAP rfc接口的新思路


前言:为了提高SAP二次开发的效率,想用python写个简单的脚本工具,与SAP 中frc的接口自动对接。但是,国内的博客中有关此内容的博文很少,且时间久远。查了国外的文章,有一些文章有涉及此内容,不过在python这一块还是有一定的问题。python的 pysaprfc 模块的维护更新和文档都是较少的,有之前的博主分享过经验说用pysaprfc模块连接SAP传输的值是乱码,不知解决了吗。所以,积累前人的经验,以及结合python语言的跨平台性的不足的这些特点,我使用的是使用Java搭建中间件,综合python和Java语言的优势。
在这里插入图片描述
如图:Java作为中间层可以利用其强大的跨平台性与SAP系统连接;Java又与python具有良好的可连接性且非常简单;下面将主要从python和Java的代码层去分析

java与SAP的连接:

所需jar包:dom4j-1.6.1.jar,sapjoc3.jar,者两个jar包也是为自己写的连接类服务的,详细教程看两个jar包的文档。
自己写的连接类:

SAPconn.java

public class SAPConn {
	private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
	static{
		Properties connectProperties = new Properties();
		connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.18.12");  //SAP集团的ip
		connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  "00");            
		connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "400");            //集团号
		connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "username");       //登录的用户名       
		connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password");       //登录的密码 
		connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "zh");  
		connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");        
		connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10"); 
		createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
	}
	
	/**
	 * 
	 * @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){
			//log.error("Create Data file fault, error msg: " + e.toString());
			System.out.println("Create Data file fault, error msg: " + e.toString());
			throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
		}
	}
	
	/**
	 * 
	 * @return
	 */
	public static JCoDestination connect(){
		JCoDestination destination =null;
		try {
			destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
		} catch (JCoException e) {
			//log.error("Connect SAP fault, error msg: " + e.toString());
			System.out.println("Connect SAP fault, error msg: " + e.toString());
		}
		return destination;
	}
}

rfc.java

class omjson{
    	String FIELDNM;
    	String FIELDTEXT;
		public String getFIELDNM() {
			return FIELDNM;
		}
		public void setFIELDNM(String fIELDNM) {
			FIELDNM = fIELDNM;
		}
		public String getFIELDTEXT() {
			return FIELDTEXT;
		}
		public void setFIELDTEXT(String fIELDTEXT) {
			FIELDTEXT = fIELDTEXT;
		}
		@Override
		public String toString() {
			
			return FIELDNM+":"+FIELDTEXT;
		}
    	
    }
	public String rfcs(String name) {
		JCoFunction function = null;
		JCoDestination destination = SAPConn.connect();
		List<omjson> list = new ArrayList<omjson>();
		try {
			//你的SAP frc 接口的名字
			function = destination.getRepository().getFunction("Z_RFC_XML");
			JCoParameterList input = function.getImportParameterList();
			//输入你传入SAP rfc 接口的参数,如果没有就不用传了
			input.setValue("TNAME", name);
			function.execute(destination);
			JCoParameterList tblexport = function.getTableParameterList();
			String msg = tblexport.toXML();
			Document document = DocumentHelper.parseText(msg);
			Element employees = document.getRootElement();
            for (Iterator i = employees.elementIterator(); i.hasNext(); ) {
                Element employee = (Element) i.next();
                for (Iterator j = employee.elementIterator(); j.hasNext(); ) {
                    Element node = (Element) j.next();
                    omjson om = new omjson();
                    //System.out.println(node.getName() + ":" + node.getText());
                    for (Iterator k = node.elementIterator(); k.hasNext(); ) {
                    	HashMap<String, String> map = new HashMap<String, String>();
                        Element item = (Element) k.next();
                          if(item.getName().equals("FIELDNM")){
                        	  om.setFIELDNM(item.getText());
                          }else if(item.getName().equals("FIELDTEXT")){
                        	  om.setFIELDTEXT(item.getText());
                          }
                    }
                    list.add(om);
                }
            }
		}catch (Exception e) {
			e.printStackTrace();
		}
	return list.toString();
	}

到这里我们连接类就写好了,不过我们并不是要用java作为脚本语言,所以将写的所有类打包成jar包,加上下载的两个jar包,一共四个jar包,我们会在python中调用。

Java与python的连接:

python_sap.py:

import jpype
# """通过java的接口调用SAP接口,指定输出的表名"""  #路径问题,可能不支持中文
jarpath4 = os.path.join(os.path.abspath('.'), "D:/script/RFCTest.jar")
jarpath3 = os.path.join(os.path.abspath('.'), "D:/script/SAPConn.jar")
jarpath2 = os.path.join(os.path.abspath('.'), "D:/script/dom4j-1.6.1.jar")
jarpath1 = os.path.join(os.path.abspath('.'), "D:/script/sapjco3.jar")
#加载多个Jar包
#注意这里的java的jdk安装默认的路径,如果不是默认的路径需要指定路径
#如 # startJVM("C:/Program Files/Java/jdk1.8.0_221/jre/bin/server/jvm.dll","-ea","-Djava.class.path=%s;%s;%s;%s;%s;%s" % (jarpath, #jarpath, jarpath1, jarpath2, jarpath3, jarpath4)
jpype.startJVM("-ea", "-Djava.class.path=%s;%s;%s;%s;%s;%s" % (jarpath, jarpath, jarpath1, jarpath2, jarpath3, jarpath4))

首先python需要加载jpype模块,用来调用java的程序。在python中只需要这么几行代码就调用了java刚才产生的jar包,然后就可以写逻辑代码,将从SAP传来的值进行分析。具体怎么用python调用java,可以看网上详细教程,很多例子。
注意:python的字符集需要调整,不然会乱码,中文可以用UTF-8,或者GB2313

加载sapjoc3.dll

最后一步,把sapjoc3.dll这个文件放到jdk的bin下,这个文件可能是SAP系统自带的,可以找找,没有就去网上下载一个也是可以的。

总结:其实这种方法是有一点复杂,起码还要懂点java的基础。我写这个博客并不是说这种方式多么厉害高深,我只是提供一种python 调用SAP rfc接口的一种思路,而且是成功的案例。python在数据分析,爬虫,脚本等有自己强大的地方,而java在跨平台等有其优势,扬长避短发挥各自优势,这也是这篇博客所想表达的。如果各位看客有新想法,也可以把自己的连接放到评论区,分享学习。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/cqq1171422470/article/details/103812277
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢