针对Java程序调用RFC的API——JCo_第1页
针对Java程序调用RFC的API——JCo_第2页
针对Java程序调用RFC的API——JCo_第3页
针对Java程序调用RFC的API——JCo_第4页
针对Java程序调用RFC的API——JCo_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、要用Java程序远程调用ABAP函数可以使用SAP提供的RFC针对Java程序的APIJCo。0.JCo的安装很不幸,虽然JCo是用Java语言编写的但却是平台相关的。(具体来说,JCo的Java包sapjco.jar确实是平台无关的,但是运行JCo需要RFC库支持,而RFC库是平台相关的)目前为止我还只有在Windows系统中安装的版本,因为JCo不是一个开源组件,甚至在SAP官方下载它是需要SAP Service MarketPlace的用户帐号的。目前我手上的是JCo2.1.6Windows版本。除了API文档和一些DEMO程序,你需要用到的有3个文件:librfc32.dll,sapj

2、corfc.dll,sapjco.jar。 安装配置步骤如下:(1).将sapjco.jar导入到你的项目库路径中。SAP官方的指导是要你配置CLASSPATH,这种方法在我看来不值得提倡,因为eclipse或netBeans这样的IDE可以帮你轻松导入jar库而无需摆弄系统环境变量。(2).将sapjcorfc.dll文件拷贝至sapjco.jar所在的文件夹中。注意,这两个文件必须放在同一个文件夹里,它们俩必须像热恋中的情人一样一直黏在一起才能使JCo正常工作。(3).将librfc32.dll文件拷贝至C:WINDOWSsystem32中。如果系统中已安装过SAP客户端,那么可

3、能本来就已经有一个librfc32.dll在那里了,SAP官方要求你覆盖那个文件,这是一种很不负责的方法。当你覆盖这个文件后很可能你的SAPLogon就无法工作了。正确的做法是备份原来的文件,然后尝试覆盖后使用SAPLogon,如果出问题了,把原来那个文件找回来。我在安装了710 Final Release版本的SAPLogon机器上使用原来的librfc32.dll运行JCo目前还没有发生什么异常。 好了,到现在为止,JCo算是安装好了,我们可以开始编写程序了。 1.使用JCo调用远程ABAP函数使用Java程序远程调用ABAP函数的大致流程是这样地:先要有SAP系统所在

4、服务器的IP地址、要登录的SAP系统的客户端号、系统编号、用户名、用户密码,有了这些后,就可以建立一个到该SAP系统的连接,然后在这个连接上调用允许远程调用的函数,得到调用后的结果,关闭连接。这其中牵涉到一些细节,我们先看程序: package jcousage; import com.sap.mw.jco.IFunctionTemplate;import com.sap.mw.jco.JCO;import java.util.Properties; public class TestJCo     public static voi

5、d main(String args) /*获得一个到SAP系统的连接  START  */        Properties logonProperties = new Properties();        logonProperties.put("jco.client.ashost","23"); /系统的IP地址    &#

6、160;   logonProperties.put("jco.client.client","800");           /要登录的客户端        logonProperties.put("jco.client.sysnr","00");      

7、60;      /系统编号        logonProperties.put("jco.client.user","young98");         /登录用户名        logonProperties.put("jco.client.passwd",&

8、quot;password");      /用户登录口令        /用上述条件创建一个连接对象        JCO.Client myConnection = JCO.createClient( logonProperties );/*获得一个到SAP系统的连接  END    */     

9、60;  myConnection.connect();       /进行实际连接        /如果连接不为null并且处于活动状态        if (myConnection != null && myConnection.isAlive()           

10、;  /从连接获得一个逻辑意义上的“仓库”对象(Repository)            JCO.Repository myRepository =                 new JCO.Repository("Repository",  /只是一个名字  

11、;                                 myConnection); /活动的连接            /要调用的SAP函数名称 

12、           String strFunc = "BAPI_FLIGHT_GETLIST"            /从“仓库”中获得一个指定函数名的函数模板            IFunctionTemplate ft = myRepository.

13、getFunctionTemplate(strFunc.toUpperCase();            /从这个函数模板获得该SAP函数的对象            JCO.Function function = ft.getFunction();          

14、0; /获得函数的import参数列表            JCO.ParameterList input = function.getImportParameterList();             /设定一个import参数的值。参数名为“MAX_ROWS”,设定值为10       &#

15、160;    input.setValue(10, "MAX_ROWS"); /*设定结构参数  START  */            /如果参数是一个结构,用参数名获得一个对应类型的结构对象            JCO.Structure sFrom = input.getStructur

16、e("DESTINATION_FROM");            /设定结构中的变量。变量名为“CITY”,设定值为“NEW YORK”            sFrom.setValue("NEW YORK", "CITY");       &#

17、160;    /将处理好的结构赋给该参数            input.setValue(sFrom, "DESTINATION_FROM");/*设定结构参数  END    */*设定table参数  START  */            /用参数名获得一

18、个对应类型的内部表对象            JCO.Table tDateRange = function.getTableParameterList().getTable("DATE_RANGE");             /接下来基本属于体力活了.        

19、;    /新增一条空行            tDateRange.appendRow();            /定位到第0行            tDateRange.setRow(0);   

20、60;        /设定该行对应变量            tDateRange.setValue("I", "SIGN");            tDateRange.setValue("EQ", "OPTION");&#

21、160;           tDateRange.setValue("20040330", "LOW");            /新增一条空行            tDateRange.appendRow();  

22、          /定位到第1行            tDateRange.setRow(1);            /设定该行对应变量            tDateRa

23、nge.setValue("I", "SIGN");            tDateRange.setValue("EQ", "OPTION");            tDateRange.setValue("20040427", "LOW"); 

24、;           /./*设定table参数  END    */            /执行函数            myConnection.execute(function);    

25、         /在执行函数后可用相同方式获得输出结果            JCO.Table flights = function.getTableParameterList().getTable("FLIGHT_LIST");            /JCO.Table对

26、象可以直接输出到html文件            flights.writeHTML("C:/function.html");            /也可以如下单独获得表中个别变量            System.out.println(&q

27、uot;Airline" + "tt"                               + "from city" + "t"       

28、0;                       + "to city" + "tt"                     &

29、#160;         + "departure time" + "tt"                               + "price"

30、+ "t"                               + "CURR");            for (int i = 0; i

31、 < flights.getNumRows(); i+)                 flights.setRow(i);                System.out.println(flights.getString("AIRLINE") + "t&

32、quot;                                 + flights.getString("CITYFROM") + "t"       

33、60;                         + flights.getString("CITYTO") + "t"                &

34、#160;                + flights.getDate("FLIGHTDATE") + "t"                        

35、60;        + flights.getDouble("PRICE") + "t"                                 + fligh

36、ts.getString("CURR");                        /断开连接            myConnection.disconnect();      &

37、#160; else             System.out.println(false);            /: 首先,将连接需要的信息放到一个Properties里,对应的键值都是固定的。需要注意的是给定的用户名必须有足够的权限进行远程调用。JCO.Client myConnection = JCO.createClient( logonProperties )

38、;这样就创建了一个到SAP系统的连接对象了。接着只要在这个对象上调用connect()方法就能激活连接。为了保证这个连接确实可用,加上这一句:if (myConnection != null && myConnection.isAlive()接下来比较麻烦,先要从这个活动的连接上拿到一个“仓库”,然后从这个“仓库”里拿到函数模板,再从函数模板里拿到对应函数对象。JCO.Repository myRepository =             

39、60;   new JCO.Repository("Repository",  /只是一个名字                                      

40、  myConnection); /活动的连接String strFunc = "BAPI_FLIGHT_GETLIST"IFunctionTemplate ft = myRepository.getFunctionTemplate(strFunc.toUpperCase();JCO.Function function = ft.getFunction();整个过程很唬人,其实也就那么回事。这里我们调用的是一个叫“BAPI_FLIGHT_GETLIST”函数,这个函数在SAP系统中被声明为Remote-Enabled Module,能够被远程调用的函数都必须声明为

41、Remote-Enabled Module。好了,我们现在有函数对象了。我们知道,SAP函数主要就是有5个输入输出接口:Import、Export、Changing、Tables、Exceptions。其中除了Changing在远程调用中是不被允许的外,其他都是可用的属性:Import:通过在函数对象上调用getImportParameterList()方法获得Import变量列表。JCO.ParameterList input = function.getImportParameterList();Export:在函数被执行后通过在函数对象上调用getExportParameterList(

42、)方法获得Export变量列表。JCO.ParameterList output = function.getExportParameterList();Changing:不支持。Tables:通过在函数对象上调用getTableParameterList()方法获得Tables变量列表。JCO.ParameterList tables = function.getTableParameterList();Exceptions:可通过在函数对象上调用getExceptionList()方法获得Exceptions变量数组,也可调用getException(java.lang.String ke

43、y)获得单个异常对象。JCO.AbapException abapExceptions = function.getExceptionList();JCO.AbapException abapException = function.getException( "1" );Import、Export、Tables所获得的都是JCO.ParameterList对象。 如果参数是基本类型,则可直接设定:input.setValue(10, "MAX_ROWS");Object object = output.getValue("MAX_R

44、OWS");当然你这样getValue得到的只能是一个Object对象,如果你知道你会得到什么类型(一般情况下你应该知道),你可以直接get这个类型。比如,我们知道"MAX_ROWS"是个int值,所以:int maxRows = output.getInt("MAX_ROWS"); 如果参数是一个结构(如果你是个面向对象的程序员,请回忆一下C语言中的结构变量,谢谢),那么你得先得到一个对应此参数的结构对象,然后对结构中的变量成员get或者set:JCO.Structure sFrom = input.getStructure(&qu

45、ot;DESTINATION_FROM");sFrom.setValue("NEW YORK", "CITY");当然如果是Import的话最后别忘了把这个结构放回列表中:input.setValue(sFrom, "DESTINATION_FROM"); 在对Tables的参数进行操作时,也得先得到一个与该参数内部表对应的内部表对象:JCO.Table tDateRange = tables.getTable("DATE_RANGE");现在这个内部表对象还是空的,所以要先加一行数据,然后将一

46、个逻辑指针指向该行,再进行各个元素的赋值或取值:tDateRange.appendRow();tDateRange.setRow(0);tDateRange.setValue("I", "SIGN");tDateRange.setValue("EQ", "OPTION");tDateRange.setValue("20040330", "LOW");内部表对象支持直接将表内容发送到HTML文件:JCO.Table flights = function.getTablePara

47、meterList().getTable("FLIGHT_LIST");flights.writeHTML("C:/function.html");想知道内部表中有几条数据,可以调用getNumRows()方法:int rows = flights.getNumRows(); 结束调用时要记得断开连接:myConnection.disconnect(); 2.使用连接池很多时候我们需要进行大量连接,SAP系统本来就脆弱,连接再一多那真的是老牛拉车了。所以我们要用连接池进行连接。下面是一个使用连接池的例子:package jcousag

48、e; import com.sap.mw.jco.JCO;import java.util.Properties; public class UsageForPool     public static void createConnectionPool( String poolName,                     

49、0;                          int maxConnection,                     

50、60;                          Properties logonProperties)         JCO.Pool pool = JCO.getClientPoolManager().getPool(poolName);  &#

51、160;     if(pool = null)             JCO.addClientPool( poolName,            / 连接池名              

52、60;                maxConnection,       / 最大连接数                        

53、0;      logonProperties );   / logon设定参数                public static JCO.Client getConnectionInPool( String poolName )         JCO.Client connection = null; &#

54、160;      JCO.Pool pool = JCO.getClientPoolManager().getPool(poolName);        if(pool != null)             connection = JCO.getClient(poolName);      

55、0;         return connection;        public static void releaseConnection( JCO.Client connection )         JCO.releaseClient( connection );        public static void remo

56、veConnectionPool(String poolName)         JCO.removeClientPool(poolName);         public static void main(String args)         Properties logonProperties = new Properties();   

57、0;    logonProperties.put("jco.client.ashost","23");        logonProperties.put("jco.client.client","800");        logonProperties.put("jco.client.sysnr",

58、"00");        logonProperties.put("jco.client.user","young98");        logonProperties.put("jco.client.passwd","password");        String poolNam

59、e = "ThePool"        createConnectionPool(poolName, 6, logonProperties);        JCO.Client connection = getConnectionInPool(poolName);        connection.connect();   

60、0;    if (connection != null && connection.isAlive()             System.out.println("Connection is alive!");            releaseConnection(connection); &

61、#160;          removeConnectionPool(poolName);        else             System.out.println("Connection FALSE!");        &

62、#160;    首先,我们仍然需要一个Properties对象用来建立连接,不过这次是建立的连接是一个连接池:JCO.addClientPool( poolName, maxConnection, logonProperties );这个方法同时还需要池的名字以及最大连接数一起作为参数。当然在新建一个连接池之前,检查一下有没有相同名字的池已经存在是一个好习惯。有了池我们就可以在连接池里获得连接啦:JCO.Client connection = JCO.getClient(poolName);然后在这个连接对象上激活连接就可以啦:connection.connec

63、t();接下来就跟上面说的一样用啦,简单吧。用完别忘了释放连接:JCO.releaseClient( connection );如果连接池也不用了就删了它:JCO.removeClientPool(poolName);<% page contentType="text/html; charset=gb2312" %><% page language="java" import="java.util.*" pageEncoding="UTF-8"%><% page import=&quo

64、t;com.sap.mw.jco.IFunctionTemplate,com.sap.mw.jco.JCO" %><!DOCTYPE HTML PUBLIC "-/W3C/DTD HTML 4.01 Transitional/EN"><html> <head> </head> <body> <input id="text1" type="text" name="text1"/><SCRIPT> var obj = window.dialogArguments;var t1 = document.getElementById('text1');t1.value = obj1;</SCRIPT> <%String aa =request.getParameter("aa");String bb =request.getParameter("bb"); /*获得一个到SAP系统的连接 START */ Properties logonProperties = new Properties(); logonProperti

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论