Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos
685

首先,如果不知道JCO是什么?和JCO能干什么的?自己去谷歌,这里就不解释了。我们先来看一下JCO 3.0是如何连接SAP Netweaver  的。

  JCO 3.0与2.0有许多的不同,它对SAP的连接更加的快捷、稳定和高效,不相信的,可以在学完3.0技术后,再去了解一下2.0的技术吧。

  JCO 3.0对SAP的接口操作一般有两种方式:一种是以Web服务器作为客户端,SAP Netweaver为服务端,传输和接收数据;另一种是作为Server端,但是这种方式我没怎么了解,只是测试过,在Web端stop和start Web Server后,SAP会产生什么样的反应;而且在网上大量的资料也都是关于第一种的连接方式。

     所以,在此,我就只介绍第一种连接方式吧,第一种连接SAP方式的原理是:

    以Web Server(Tomcat)作为客户端,JCO技术作为中间接口桥梁,SAP作为服务的,用户在Web端所有的操作数据最终将通过RFC回滚到SAP上去维护,SAP会自动处理这些数据,这和BAPI原理是一样的。许多公司,上线了SAP后,需要将原来公司内部的ERP软件上的数据写入SAP,也是通过JCO技术作为桥梁来处理的。

JCO <wbr>3.0最新技术详解

2、连接第一步:

   JCO连接SAP时,先要创建一个连接池,它的连接信息保存在一个Properties文件里。

 

public static boolean creatSapPros(String filename, String stuffix,

String host, String sysnr, String client, String user, String pass,

String lang, String pool_capacity, String peak_limit) {

Properties pros = new Properties();

boolean iscreate = false;

String sysno = "";

if (sysnr.equals("AFD")) {

sysno = "00";

}

if (sysnr.equals("AFQ")) {

sysno = "00";

}

if (sysnr.equals("AFP")) {

sysno = "01";

}

if (lang.equals("")) {

lang = "ZF";

}

pros.clear(); // 先清空

pros.setProperty(DestinationDataProvider.JCO_ASHOST, host);

pros.setProperty(DestinationDataProvider.JCO_SYSNR, sysno);

pros.setProperty(DestinationDataProvider.JCO_CLIENT, client);

pros.setProperty(DestinationDataProvider.JCO_USER, user);

pros.setProperty(DestinationDataProvider.JCO_PASSWD, pass);

pros.setProperty(DestinationDataProvider.JCO_LANG, lang);

pros.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY,

pool_capacity);

pros.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, peak_limit);

iscreate = createFiles(filename, stuffix, pros);

if (iscreate) {

return true;

} else {

return false;

}

}

public static boolean isFileExist(String filename, String stuffix) {

File file = new File(filename + "." + stuffix);

if (file.exists()) {

try {

System.out.println("路徑:" + file.getCanonicalPath());

} catch (IOException e) {

e.printStackTrace();

}

return true;

} else {

return false;

}

} 

public static boolean createFiles(String filename, String suffix,

Properties pros) {

File file = new File(filename + "." + suffix);

FileOutputStream fos = null;

if (!file.exists()) {

try {

System.out.println("********* 正在寫入文件 **********");

fos = new FileOutputStream(file, false);

pros.store(fos, "Author: EthanLiang");

fos.close();

return true;

} catch (FileNotFoundException e) {

System.out.println("-------- 找不到文件! ---------");

e.printStackTrace();

return false;

} catch (IOException e) {

System.out.println("-------- 內容寫入失敗! ---------");

e.printStackTrace();

return false;

} finally {

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

} else {

return false;

}

}

上面我写了一个创建Property文件的方法,这样的话,这个文件是保存在Web服务器里面的,至于在什么位置,自己创建后,有兴趣可以去找找看。   

3、第3步:开始连接SAP:

   这一步,我们也可以叫它“登录SAP”,其实JCO实现的原理是和SAP的客户端原理是一样的,你要登录到SAP,首先是要先登录,第一步是创建了一个连接池,接下来咱们就要把用户的登录信息写在这个文件里,SAP会通过RFC自己去调用的。

   public synchronized JCoDestination getJCoDestination(String filename,

String stuffix, String host, String sysnr, String client,

String user, String pass, String lang) {

boolean isexist = false; // 判断文件是否存在

boolean isCreate = false; // 穿件pro文件

JCoDestination destination;

isexist = FileUtil.isFileExist(filename, stuffix);

if (isexist == true) {

System.out.println("-------- 文件已經存在 -----------");

try {

destination = JCoDestinationManager.getDestination(filename);

return destination;

} catch (JCoException e) {

System.out

.println("---------- 獲取JCoDestination失敗! -----------");

e.printStackTrace();

return null;

}

} else {

isCreate = FileUtil.creatSapPros(filename, stuffix, host, sysnr,

client, user, pass, lang, "3000", "500");

if (isCreate == true) {

try {

destination = JCoDestinationManager

.getDestination(filename);

System.out

.println("---------- 獲取JCoDestination!成功,正在返回數據 -----------");

return destination;

} catch (JCoException e) {

System.out

.println("---------- 無法獲取JCoDestination! -----------");

e.printStackTrace();

return null;

}

} else { // 如果文件不存在

return null;

}

}

}

  ===================================================================

上面的连接SAP代码,我设计了一个非常人性化的代码,我写了一个getJCoDestination的方法,该方法用来连接SAP,连接成功后会返回远程连接目标信息,也就是JCoDestination。代码中,去登录前,先判断property文件是否已经创建好了,如果创建好了,就直接取出文件登录信息去连接SAP,如果没有,就先去创建一次,创建的代码请看第2步

JCoDestinationManager.getDestination(filename);

这代码就是根据你创建的property文件的命名去获取里面的登录信息;

这里的filename是你自己随机定义命名的,你创建property文件时,是用什么名字,你getDestination也要用什么名字,这个filename是不包含property后缀名的,一定要切记。比如:createFiles(filetest, pros,Properties pros) ;这个方法是【2】创建property文件的方法,我们以上假设了创建一个property文件,filename是【filetest,后缀名是【pros】,创建成功后,你会看服务器上多出了个【filetest.pros】的文件,这个文件就是保存SAP登录信息的文件;

然后登录时就应该是:

JCoDestinationManager.getDestination(filetest);

成功连接了SAP后,可以测试一下有没连接成功,可以打印一下连接信息:

//getJCoDestination要传的参数自己去写吧,我自己做个范例而已。

Destination dest= getJCoDestination(String filename,

String stuffix, String host, String sysnr, String client,

String user, String pass, String lang);

System.out.println(destination.getAttributes());

4、当成功连接了SAP后,开始与SAP交互了:

 

   Java同JCO技术与SAP进行交互的时候,主要是通过SAP 的RFC进行操作,也就SAP的Function,这个Function可以是SAP任何的Function,当然要成功连接Function前,请记得先去SAPFunction的【属性】设置里,选择【Remote-Enable Module立即开始】,要切记啊,不然连接不到Function,如果是自己开发的Function,还要激活它这个Function才能用。

首先我们通过上面的第三部连接成功后:

Destination dest= getJCoDestination(String filename,

String stuffix, String host, String sysnr, String client,

String user, String&bbsp;pass, String lang);

//开始连接function

try {

JCoFunction fun = dest.getRepository()

   .getFunction(ZRFC_PRICE_STATUS);

} catch (JCoException e) {

  fun = null;

System.out.println("JCO異常,無法獲取Function");

e.printStackTrace();

}

有没连接成功,可以打印一下function.getName()来看看;

5、获取接口参数:

   做ABAP开发的都知道,ABAP的Functionz主要有四个接口:Export、Import、Changing和Table;

   Function连接成功后,我们就开始获取这四个接口的参数;首先是获取到这个三个接口:

  

JCoParameterList imlist= function.getImportParameterList();

JCoParameterList emlist= function.getExportParameterList();

JCoParameterList tmlist= function.getTableParameterList();

JCoParameterList cmlist= function.getChangingParameterList();

接着我们可以开始向SAP传数据,如果不需要传递数据,可以直接跳过以下的步骤。我们来往function的import接口里的参数传,其他的三个接口也类似,其它三个借口的传法,可以去参考API的案例或者去百度。

imlist.setValue("STATUS", "D"); // 傳入參數

imlist.setValue("VBELN_LOW", vbeln.trim()); // 傳入參數

6、开始调用function:

   try {

     JCoParameterList imlist= function.getImportParameterList();

     JCoParameterList tmlist= function.getTableParameterList();

      imlist.setValue("STATUS", "D"); // 傳入參數

      imlist.setValue("VBELN_LOW", vbeln.trim()); // 傳入參數

JCoContext.begin(destination);   //开启一个事务

       //开始执行function

function.execute(destination);  

   //获取function返回的数据,因为我的function执行成功后,abap返回的数据是存放在table接口,所以我以上是这样去获得数据,如果你想返回在export里面,那就用export的方式去获取

   JCoTable tab = tmlist.getTable("IT_RETURN");

   for (int i = 0; i < tab .getNumRows(); i++) {

tab.setRow(i);   //设置指针位置,这个很重要

     //获取出table接口里名为“IT_RETURN”的表的数据

     tab.getString("VBELN");   //訂單號

tab.getString("NAME1");   //買 方

tab.getString("NAME2");  //付款人

tab.getString("NAME3");  //收貨人

   }

      

       try {

JCoContext.end(destination);  //远程调用结束后可以关闭

} catch (JCoException e1) {

e1.printStackTrace();

}

   catch (JCoException e1) {

e1.printStackTrace();

}

7、最后:

   好了,Java与SAP的交互已经说完了,中间还有很多的细节和功能,你在自己按着这个思路去摸索吧。

   当然,使用JCO首先要去下载JCO 3.0的JAR文件,这里我就不提供,网上也有,想要的话,也可以问我要。JCO 3.0的压缩包里,除了有Jar包,还有API和Demo,你可以慢慢去看Demo。

    最后声明,要想成功连接SAP,JCO 3.0包里面还有一个重要“sapjco3.dll”这个文件,你必须把这个文件放在你的项目WEB-INF/lib文件夹下面,或者放在你本地的哪个位置来的?我忘了,自己去搜索一下吧,反正我不是放在本地的目录下的。这点要切记啊!


Labels in this area