博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SAP接口编程 之 JCo3.0系列(01):JCoDestination
阅读量:4616 次
发布时间:2019-06-09

本文共 10708 字,大约阅读时间需要 35 分钟。

SAP接口编程 之 JCo3.0系列(01):JCoDestination

字数2101 阅读103 评论0 

JCo3.0是Java语言与ABAP语言双向通讯的中间件。与之前1.0/2.0相比,是重新设计的产品。API和架构设计与NCo3.0比较类似,前面也说过,NCo3.0的设计参考了JCo3.0。从本篇开始,系统介绍JCo3.0编程的技术要点。

JCo3.0安装

从 可以下载JCo3.0,注意下载的时候根据操作系统JVM版本(32位还是64)选择不同的版本。安装就是解压,将文件解压到目标文件夹。以Windows系统为例,主要的文件包括:

sapjco3.dll

sapjco3.jar

SAP强烈推荐将这两个文件放在同一文件夹下。测试安装是否成功,可以在命令窗口下,进入安装文件夹,运行下面的命令:

java -jar sapjco3.jar

如果安装成功,应该显示如下界面:

jco3安装成功的显示界面

JCoDestination

JCoDestination代表后台SAP系统,程序员不用关心与SAP的连接,jco3.0运行时环境负责管理连接和释放连接。我们先以一个简单的例子看看jco3.0 JCoDestination类的一些要点。

我使用的编程环境是Eclipse,环境准备如下:

  • 新建一个Java项目,项目名为JCo3Demo。
  • 将sapjco3.jar加入到项目的build path中。注意前面所说的sapjco3.jar和sapjco3.dll要放在同一个文件夹下。
  • 在Eclipse Java项目文件夹下,新建一个文本文件,文件名命名为ECC.jocdestination, 文件的内容如下(SAP系统的连接参数的设置):

    #SAP Logon parameters!

    #Tue Dec 08 16:41:30 CST 2015
    jco.client.lang=EN
    jco.client.client=001
    jco.client.passwd=xxxxxx
    jco.client.user=STONE
    jco.client.sysnr=00
    jco.client.ashost=192.168.65.100

对照SAP GUI,不难理解:

SAP GUI

环境准备好了,先来一段最简单的代码:

package jco3.demo1;import java.util.Properties;import org.junit.Test;import com.sap.conn.jco.JCoDestination; import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; public class JCoDestinationDemo { public JCoDestination getDestination() throws JCoException { /** * Get instance of JCoDestination from file: ECC.jcodestination * which should be located in the installation folder of project */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); return dest; } @Test public void pingDestination() throws JCoException { JCoDestination dest = this.getDestination(); dest.ping(); } }

代码说明:

  • getDestination()方法中,JCoDestinationManager.getDestination("ECC")从ECC.jcodestination文件中获取连接参数,创建JCoDestination对象的实例。

    这里有一个重要的约定,JCoDestinationManager.getDestination("ECC")方法,会从Eclipse Java项目的根目录,查找ECC.jcodestination文件(文件路径和扩展名不能改变)是否存在,如果存在,从文件的内容中获取连接参数。这是DestinationDataProvider接口的一个默认实现,在开发和测试的时候还是很方便的,但如果在真实项目中使用,安全性和灵活性就不够。后面会介绍解决方法。

  • pingDestination()方法调用JcoDestination对象的ping()方法测试SAP系统的连接。

  • @Test: 使用junit进行测试

配置文件的生成

刚才我们手工编辑了ECC.jcodestination文件,对于这个配置文件,因为很多连接参数来自于DestinationDataProvider接口,如果想通过代码来创建配置文件,可以使用如下代码:

package jco3.demo2;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; import org.junit.Test; import com.sap.conn.jco.ext.DestinationDataProvider; public class DestinationFile { private Properties setProperties() { // logon parameters and other properties Properties connProps = new Properties(); connProps.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.65.100"); connProps.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); connProps.setProperty(DestinationDataProvider.JCO_USER, "STONE"); connProps.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxxx"); connProps.setProperty(DestinationDataProvider.JCO_CLIENT, "001"); connProps.setProperty(DestinationDataProvider.JCO_LANG, "EN"); return connProps; } private void doCreateFile(String fName, String suffix, Properties props) throws IOException { /** * Write contents of properties into a text file * which was named [fName+suffix.jcodestination] */ File cfg = new File(fName+"."+suffix); if (!cfg.exists()){ // file not exists // Create file output stream, not using append mode FileOutputStream fOutputStream = new FileOutputStream(cfg, false); // store the properties in file output stream // and also add comments props.store(fOutputStream, "SAP logon parameters:"); fOutputStream.close(); }else{ throw new RuntimeException("File alreay exists."); } } @Test public void createConfigFile() throws IOException { Properties props = this.setProperties(); String fileName = "SAP_AS"; // sap application server // jcodestination suffix is required by JCoDestinationManager this.doCreateFile(fileName, "jcodestination", props); } }

代码说明:

  • setProperties()方法属性参照DestinationDataProvider类的常量设置Properties的实例。
  • doCreateFile()方法根据需求的文件名,扩展名在Eclipse项目的根文件夹下,创建一个文本文件,文件的内容就是Properties实例的内容。
  • createConfigFile()方法,调用上面的两个方法,创建配置文件。

更改配置文件名的路径和扩展名

我们看到,默认情况下,SAP对配置文件的路径和扩展名都不能改变,如果我们想把文件放在任意位置,扩展名也使用其他的扩展名,有没有办法?答案是有,方法是实现DestinationDataProvider接口,并改写(override)getDestinationProperties()方法,然后通过Environment.registerDestinationDataProvider()方法进行注册。

OK, 一起来看看代码,代码分为三个部分:

  • 第一部分: 创建FileDestinationDataProviderImp类,实现DestinationDataProvider接口
  • 第二部分: 创建FileDestinationDataProvider类,注册FileDestinationDataProviderImp的实例,并提供getDestination()方法供调用
  • 第三部分:调用FileDestinationDataProvider类的getDestination()方法

第一部分:DestinationDataProvider接口的实现:

package jco3.demo2;import java.io.File;import java.io.FileInputStream;import java.io.IOException; import java.util.Properties; import com.sap.conn.jco.ext.DestinationDataEventListener; import com.sap.conn.jco.ext.DestinationDataProvider; public class FileDestinationDataProviderImp implements DestinationDataProvider { private File dir; private String destName; // destination name private String suffix; public void setDestinationFile(File dir, String destName, String suffix) { this.dir = dir; this.destName = destName; this.suffix = suffix; } private Properties loadProperties(File dir, String destName, String suffix) throws IOException { Properties props = null; // create a file with name: fullName in destDirectory File destFile = new File(dir, destName+"."+suffix); if (destFile.exists()){ FileInputStream fInputStream = new FileInputStream(destFile); props = new Properties(); props.load(fInputStream); fInputStream.close(); }else{ throw new RuntimeException("Destination file does not exist."); } return props; } @Override public Properties getDestinationProperties(String destName) { Properties props = null; try { props = this.loadProperties(this.dir, this.destName, this.suffix); } catch (IOException e) { e.printStackTrace(); } return props; } @Override public void setDestinationDataEventListener(DestinationDataEventListener listener) { throw new UnsupportedOperationException(); } @Override public boolean supportsEvents() { return false; } }

第二部分: 创建FileDestinationDataProvider类,注册FileDestinationDataProviderImp的实例,并且提供getDestination()方法。

package jco3.demo2;import java.io.File;import com.sap.conn.jco.JCoDestination;import com.sap.conn.jco.JCoDestinationManager;import com.sap.conn.jco.JCoException; import com.sap.conn.jco.ext.Environment; public class FileDestinationDataProvider { public static JCoDestination getDestination() throws JCoException { File directory = new File("."); // current directory; String fileName = "SAP_AS"; String suffix = "txt"; FileDestinationDataProviderImp destDataProvider = new FileDestinationDataProviderImp(); destDataProvider.setDestinationFile(directory, fileName, suffix); Environment.registerDestinationDataProvider(destDataProvider); JCoDestination dest = JCoDestinationManager.getDestination(fileName); return dest; } }

我们看到,getDestination方法中,文件的路径,文件的扩展名,都是我们自己定义的。文件名作为JCoDestinationManager.getDestination方法的destination name。从这里也可可以看到,JCoDestinationManager.getDestination方法从哪里查找连接参数,是依赖于Environment注册的DestinationDataProvider实现

第三部分:测试代码FileDestinationDataProvidergetDestination方法:

package jco3.demo2;import org.junit.Test;import com.sap.conn.jco.JCoDestination;import com.sap.conn.jco.JCoException; public class TestFileDestinationProvider { @Test public void pingSAPDestination() throws JCoException { JCoDestination dest = FileDestinationDataProvider.getDestination(); dest.ping(); } }

DestinationDataProvider另一种实现

记得nco3.0可以将登陆参数写在代码中吗,如果我们也想将连接参数直接写在代码中,怎么做呢?刚才说过了,关键就是实现DestinationDataProvider接口,并改写getDestinationProperties()方法。不多说,上代码。

第一部分:DestinationDataProvider接口实现

package jco3.demo3;import java.util.HashMap;import java.util.Map;import java.util.Properties; import com.sap.conn.jco.ext.DestinationDataEventListener; import com.sap.conn.jco.ext.DestinationDataProvider; public class DestinationDataProviderImp implements DestinationDataProvider { /** * DestinationDataProvider is an interface * We define DestinationDataProviderImp class to implements this interface * so that we can define the logon parameters more flexibly * not just in xxx.jcodestionation file. * * The key point is that we override getDestinationProperties() method * Afterwards, instance of DestinationDataProvider should be registered * using Environment.registerDestinationDataProvider() method to take effect */ @SuppressWarnings("rawtypes") private Map provider = new HashMap(); @SuppressWarnings("unchecked") public void addDestinationProperties(String destName, Properties props) { provider.put(destName, props); } @Override public Properties getDestinationProperties(String destName) { if (destName == null){ throw new NullPointerException("Destinantion name is empty."); } if (provider.size() == 0){ throw new IllegalStateException("Data provider is empty."); } return (Properties) provider.get(destName); } @Override public void setDestinationDataEventListener(DestinationDataEventListener listener) { throw new UnsupportedOperationException(); } @Override public boolean supportsEvents() { return false; } }

第二部分:创建DestinationProivder类,提供getDestination()方法,注册DestinationDataProviderImp类的实例:

package jco3.demo3;import java.util.Properties;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; import com.sap.conn.jco.ext.Environment; public class DestinationProvider { private static Properties setProperties() { // logon parameters and other properties Properties connProps = new Properties(); connProps.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.65.100"); connProps.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); connProps.setProperty(DestinationDataProvider.JCO_USER, "STONE"); connProps.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxxx"); connProps.setProperty(DestinationDataProvider.JCO_CLIENT, "001"); connProps.setProperty(DestinationDataProvider.JCO_LANG, "EN"); return connProps; } public static JCoDestination getDestination() throws JCoException { String destName = "SAP_AS"; Properties props = setProperties(); DestinationDataProviderImp destDataProvider = new DestinationDataProviderImp(); destDataProvider.addDestinationProperties(destName, props); Environment.registerDestinationDataProvider(destDataProvider); JCoDestination dest = JCoDestinationManager.getDestination(destName); return dest; } }

第三部分:测试DestinationProvidergetDestination()方法:

package jco3.demo3;import org.junit.Test;import com.sap.conn.jco.JCoDestination;import com.sap.conn.jco.JCoException; public class TestDestionProvider { @Test public void pingSAPDestination() throws JCoException { JCoDestination dest = DestinationProvider.getDestination(); dest.ping(); } }

转载于:https://www.cnblogs.com/zfswff/p/5670223.html

你可能感兴趣的文章
关于 IOS 发布的点点滴滴记录(一)
查看>>
《EMCAScript6入门》读书笔记——14.Promise对象
查看>>
CSS——水平/垂直居中
查看>>
Eclipse连接mysql数据库jdbc下载(图文)
查看>>
Python中Selenium的使用方法
查看>>
三月23日测试Fiddler
查看>>
20171013_数据库新环境后期操作
查看>>
poj 1654 && poj 1675
查看>>
运维派 企业面试题1 监控MySQL主从同步是否异常
查看>>
Docker 版本
查看>>
poj 1753 Flip Game
查看>>
在深信服实习是怎样的体验(研发测试岗)
查看>>
Linux免密码登陆
查看>>
SpringMVC中文件的上传(上传到服务器)和下载问题(二)--------下载
查看>>
Socket & TCP &HTTP
查看>>
osip及eXosip的编译方法
查看>>
Hibernate composite key
查看>>
[CF Round #294 div2] D. A and B and Interesting Substrings 【Map】
查看>>
keepalived+nginx安装配置
查看>>
我的2015---找寻真实的自己
查看>>