跳过导航,朗读正文21CN首页

新闻 | 财经 | 汽车 | 房产 | 体育 | 娱乐 | 数码 | 生活 | 女人 | 游戏 | 旅游 | 社区 | 邮件 | VGO | 播客 | 影院

  当前位置:21CN首页 > IT频道 > 行业频道 > 正文  
 
JCo – 在Java中调用ABAP服务
2008-04-15 17:15:27  网友投稿  【 浏览字号: 点击发表评论
精彩回顾 手机 | 数码 | 笔记本 | 家电 | 下载
·30秒清除电脑垃圾 使电脑急速如飞 ·最新版QQ2008下载 搞笑FlASH下载
·篮球宝贝的性感家居照 暗访:交楼问题大曝光 ·买家电 到3C特惠场 汽车维修市场黑幕揭秘
·诺基亚N96真机欣赏 不买魅族M8十大充足理由 ·颁奖典礼有奖拿有表演 专题:两厢车导购
搜索更多 的资讯 >>>

概述

    SAPR/3系统与Java平台一样有着许多类似的技术理念,以及同样广泛的企业级用户,但是它们完全是两个不同的世界。当用户面临流程或者数据整合方面的需求的时候,就迫切需要一种高效的方式,在R/3系统和Java平台之间实时地交换数据。基于这样的需求,SAP提供了一套高效的基于RFCABAPJava进程间通讯组件:SAP Java Connector(JCo)

    本文将介绍JCo组件的架构,配置,基本使用方法以及调试,同时还将讨论如何对RFC方式调用的ABAP函数进行远程调试。

    JCo组件的基本架构如下图(引用自http://help.sap.com)所示:

    如图所示,JCo库提供了可以直接在Java程序中使用的API。该API通过JNI调用部署在客户端的SAPRFC库。该RFC库是用C语言实现的,并且与JCo库相互独立发布。但是,在下载的JCo库压缩包中也会提供。

    该组件支持Inbound(在Java代码中调用ABAP函数)和Outbound(在ABAP代码中调用Java)两种模式。本文只专注于介绍Inbound模式中,如何在Java代码远程调用ABAP函数。

安装与配置

    最新版本的JCo库可以在如下网址下载(请选择适合你的软件和硬件平台的版本,本文的示例都基于32Windows操作系统):

http://service.sap.com/connectors

    你可能需要提供SAP Service MarketPlace的用户帐号。解压缩以后,将名为librfc32.dll的文件复制到目录 {windows-dir}\system32下面。如果该文件已经存在,则覆盖它。这个文件就是SAPRFC协议实现,可以在http://service.sap.com/connectors下载其最新版本。

    然后,确保CLASSPATH环境变量中包含文件sapjco.jar所在的目录。因为这个JAR包中含有在Java程序中需要直接调用的类和接口。

    下载的压缩包中还包含了JavaDoc,文档以及示例程序供参考。

建立连接

    在执行任何操作之前,必须先建立到SAP系统的连接。本文示例使用的用户名是“DDIC”,登录密码是“minisap”,基于如下图所示系统信息:

    类JCOJco库中最主要的一个入口,它提供了许多静态方法。其中有一系列重载的createClient方法可以用来创建与SAP系统的连接信息。这些信息都保存在返回的JCO.Client类的实例中。常用的两种方式如下:

  1. 直接输入参数:

JCO.Client myConnection = JCO.createClient("000", "DDIC", "minisap", "EN", "10.0.0.11", "00");

  1. 使用Java Properties

Properties logonProperties = new Properties();             logonProperties.put("jco.client.ashost","10.0.0.11");             logonProperties.put("jco.client.client","000");                logonProperties.put("jco.client.passwd","minisap");               logonProperties.put("jco.client.sysnr","00");              logonProperties.put("jco.client.user","DDIC");

JCO.Client myConnection = JCO.createClient( logonProperties ).

    第一种方式比较简单,所有的参数都直接写在代码中。相比之下,第二种方式使用Java Properties,它好处在于,除了硬编码这种方式之外,用户也可以将连接信息保存在一个单独的.properties文件中。这样即使连接信息改变也无需改变代码,只需要修改.properties文件中的数据即可。关于.properties文件的用法,请参考相关的Java语言教程。

JCO.Client提供方法connect方法来建立从当前Java进程到SAP服务器的连接。

this.myConnection.connect();

可以使用isAlive方法来获取一个连接的状态,还可以使用disconnect方法来关闭一个连接:

if ( myConnection != null && myConnection.isAlive()) {

        myConnection.disconnect();

}

    很多情况下,频繁创建新的连接可能导致严重的性能问题。典型的情况就是在Web应用程序中,如果每个session创建一个连接,那么用户数量很多的时候系对系统来说就是一场灾难。JCo库支持以连接池的形式重用已创建的连接。只需要调用JCO类的静态方法addClientPool即可创建一个连接池,并且可以在参数中指定连接池的名字和允许同时激活的最大连接数。

如下代码演示了如何创建一个名为“Sample_Pool”的JCo连接池:

public static final String POOL_NAME = "Sample_Pool";

public static final int max_connection = 2;

……

JCO.Pool pool = JCO.getClientPoolManager().getPool(POOL_NAME);

if (pool == null) {

Properties logonProperties = new Properties();

logonProperties.put("jco.client.ashost","10.0.0.11");         logonProperties.put("jco.client.client","000");                logonProperties.put("jco.client.passwd","minisap");               logonProperties.put("jco.client.sysnr","00");              logonProperties.put("jco.client.user","DDIC");

JCO.addClientPool( POOL_NAME, // pool name

            max_connection, // max num of connections,

            logonProperties); // properties

}

创建好连接池之后,可以通过如下代码来从连接池中获取一个连接:

mConnection = JCO.getClient(POOL_NAME);

在连接使用完毕之后,不要忘记使用releaseClient方法释放当前连接:

JCO.releaseClient( myConnection ).

如果需要移除连接池,则可以使用如下代码:

      

JCO.removeClientPool(POOL_NAME);

    移除连接池将导致其中所有的活动连接被强行关闭,所以必须在确保连接池中所有的连接都不再被使用的时候才能执行该操作。

调用Function Modules

    为了演示如何使用JCo库来调用远程的ABAP函数,本文示例中使用NetWeaver ABAP试用版系统中的一个样例函数BAPI_FLIGHT_GETLIST

    JCo库使用RFC的方式来调用ABAP中的函数,所以被调用的函数必须已经勾选“Remote-enabled”属性。如下图所示:

    调用一个函数之前,需要知道函数的元数据,比如函数名字,输入输出参数等等。在JCo库中,必须通过类JCO.Repository来获取所有的ABAP函数的元数据,所以第一步是创建一个JCO.Repository类的对象:

    JCO.Repository myRepository = new JCO.Repository("Repository",  myConnection);

    JCO.Repository类的构造函数有两个参数,第一个是可以任意指定的名字,第二个是当前使用的连接。此处也可以直接指定一个连接池的名字,JCo库将自动从该连接池中获取连接。

    此时,必须保证该连接使用的用户名在目标SAP服务器上有足够的权限。

    获得JCO.Repository类的实例之后,就可以通过该实例来获得函数的信息。如下代码演示了如何获取函数BAPI_FLIGHT_GETLIST的信息以及如何设置简单类型的参数:

String strFunc = "BAPI_FLIGHT_GETLIST";

IFunctionTemplate ft = myRepository.getFunctionTemplate(strFunc.toUpperCase());

JCO.Function funGetList = ft.getFunction();

// set up scalar parameter

JCO.ParameterList input = funGetList.getImportParameterList();

input.setValue(10, "MAX_ROWS");

JCO.Function对象提供了对应的方法来获取ABAP函数的参数列表。例如,上例中的getImportParameterList方法返回该函数的Import参数列表。

    在上面的示例代码中,仅仅设置了一个最简单的int类型的参数。事实上,setValue方法有许多重载形式,允许设置各种复杂类型的参数,比如structure类型和table类型的参数。而且,除了通过参数名字引用要设置的参数之外,还可以通过参数的索引来引用一个参数。

    在设置structuretable类型的参数之前,需要通过JCO.Function对象的方法获取相应的JCO.StructureJCO.Table对象,然后才可以使用对每个字段进行赋值。

    在我们使用的函数BAPI_FLIGHT_GETLIST中,Import参数中的DESTINATION_FROM是一个structure,其中包含一个CITY字段。如下代码演示了如何将CITY字段赋值为“NEW YORK”:

// set up structure parameter

JCO.Structure sFrom = input.getStructure("DESTINATION_FROM");

sFrom.setValue("NEW YORK", "CITY");

input.setValue(sFrom, "DESTINATION_FROM");

    类似地,可以使用JCO.Function对象的getTableParameterList方法拿到Table参数列表。下面的代码演示了如何拿到一个名为DATE_RANGETable参数并且为它创建两行:

// set up table parameter

JCO.Table tDateRange = funGetList.getTableParameterList()

.getTable("DATE_RANGE");

tDateRange.appendRow();

tDateRange.setRow(0);    

tDateRange.setValue("I", "SIGN");

tDateRange.setValue("EQ", "OPTION");

tDateRange.setValue("20070606", "LOW");

tDateRange.appendRow();

tDateRange.setRow(1);    

tDateRange.setValue("I", "SIGN");

tDateRange.setValue("EQ", "OPTION");

tDateRange.setValue("20070704", "LOW");

参数设置完毕之后,可以通过JCO.Client对象的execute方法执行远程调用:

    myConnection.execute(funGetList);

获得输出参数的方法与输入参数完全一样。下面的代码演示了如何获取一个包含返回值的Table参数,并且输出它的内容:

// get table results

JCO.Table flights = funGetList.getTableParameterList().getTable(

     "FLIGHT_LIST");

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

flights.setRow(i);

System.out.println("Airline ["

+ flights.getString("AIRLINE")

            + "] from city "

+ flights.getString("CITYFROM")

            + " to city "

+ flights.getString("CITYTO")

            + ", departure time is "

+ flights.getDate("FLIGHTDATE"));

}

JCO.StructureJCO.Table都继承自类JCO.RecordJCO.Record对每种类型的参数都提供了对应的getset方法,并且在运行时自动进行Java数据类型和ABAP数据类型之间的转换。限于篇幅,本文不再详叙,请参考JCo库的JavaDoc文档。

在使用JCo库的过程中,主要有两种类型的异常需要处理:

  1. JCO.AbapException

如果ABAP函数执行过程中出现异常,则在Java进程中会触发该异常。

  1. JCO.ConversionException

    当执行参数的getset方法时,如果在Java类型和ABAP类型之间转换失败,则会触发该异常。

    作为一种最佳实践,建议使用try-catch封装使用JCo库进行参数设置和函数调用的代码,处理上述两种异常,并且在finally代码块中,释放当前所使用的连接。

(编辑:似水)
21CNIT最终页推荐
今日热点
手机 数码 家电 软件下载
意想不到的概念笔记本 点兵热门酷睿双核电脑 三大芯片巨头围攻英特尔
下一篇:B2B搜索 跨国采购商的必备功课
热门电影排行
夺帅
3K时代
极速飚风
瞬间激情 | 火车与玫瑰 | 马樱丹 | 超时空战士
| 黑帮太保 | 外星帝国 | 天国车站 | 明明
 点播更多    

热门剧集排行
夜郎王
廖家
给我一片蓝天
心不再遥远 | 东方母亲 | 广州教父
天使在线 | 鸦片战争演义 | 天下有情之甜蜜蜜
 点播更多    
 
 
资讯推介

T61与R61拆解对比

夏普WILLCOM 03图赏
·三大芯片巨头围攻英特尔
·AMD美洲狮Intel迅驰2笔记
·4999元热卖双核笔记本
·索尼爱立信Z780手机评测
·首批TD手机销量调查
·高性价比全手动DC选购
·四大品牌超级长焦选谁
·两千元以下超值DC推荐
精彩视频

曝光《木乃伊3》李连杰和杨紫琼的片段
《木乃伊3》精彩片段曝光

李亚鹏打人事件落幕 双方道歉言和
李亚鹏打人事件落幕
·女孩目睹母亲被碾
·风靡美国的脑残舞蹈
·90后小夫妻吵架笑死人
·特幽默的动画片乒乓小子
好书推荐[免费]
·[新书]无字天书
·[灵异]盗墓之王
·[都市]我们是传奇
·[都市]我的天师女友
·[职场]杜拉拉升职记
·[原创]混也是种生活
·[历史]谁杀死了秦帝国
·[游戏]游手好钱
·[预言]卜王之王
·[财经]金融街
社区贴图
四名16岁香港女生闯欧洲
四名16岁香港女生闯欧洲
?从袁老的"奢侈"看不到网友仇富?
网友都不仇富袁老?
·极品男爬树上与警察斗嘴
·中国大片被骂排行榜
·最牛老伯踢阿扁的屁股
·让你笑抽筋的CS漫画
·史上最不要脸的鞋店
·美国FBI犯罪心理测设题
·美女的野外诱惑
·一生只有你的清纯
宽频影院
插班师姐
插班师姐
天下无丐
天下无丐
热血刑警
热血刑警
 
公司简介  |  广告服务  |  网站导航  |  合作伙伴  |  诚征代理  |  联系我们