JCO为我们提供了另外一种连接的方法:DestinationDataProvider,通过它我们就可以将一个连接变量信息存放在内存里。

import java.util.HashMap;
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.DataProviderException;
import com.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;public class CustomDestinationDataProvider
{/*** 配置生成连接* qj*/static class MyDestinationDataProvider implements DestinationDataProvider{private DestinationDataEventListener eL;private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();// 实现接口:获取连接配置属性public Properties getDestinationProperties(String destinationName){try{//read the destination from DBProperties p = secureDBStorage.get(destinationName);if(p!=null){//check if all is correct, for exampleif(p.isEmpty())throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);return p;}return null;}catch(RuntimeException re){throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);}}public void setDestinationDataEventListener(DestinationDataEventListener eventListener){this.eL = eventListener;}public boolean supportsEvents(){return true;}//implementation that saves the properties in a very secure way 添加连接配置属性void changeProperties(String destName, Properties properties){synchronized(secureDBStorage){if(properties==null){if(secureDBStorage.remove(destName)!=null)eL.deleted(destName);}else{secureDBStorage.put(destName, properties);eL.updated(destName); // create or updated}}}} // end of MyDestinationDataProvider//business logicvoid executeCalls(String destName){JCoDestination dest;try{dest = JCoDestinationManager.getDestination(destName);dest.ping();System.out.println("Destination " + destName + " works");}catch(JCoException e){e.printStackTrace();System.out.println("Execution on destination " + destName+ " failed");}}/*** 配置连接信息* @return*/static Properties getDestinationPropertiesFromUI(){//adapt parameters in order to configure a valid destinationProperties connectProperties = new Properties();connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "***********");  //IPconnectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  "01");               //系统编号connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "620");              //客户端编号connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "user");             //用户名connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "123456");           //密码connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "ZH");               //语言return connectProperties;}public static void main(String[] args){//初始化配置信息MyDestinationDataProvider myProvider = new MyDestinationDataProvider();//register the provider with the JCo environment;//catch IllegalStateException if an instance is already registeredtry{com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);}catch(IllegalStateException providerAlreadyRegisteredException){//somebody else registered its implementation,//stop the executionthrow new Error(providerAlreadyRegisteredException);}//连接池名,名字随意取String destName = "ABAP_AS";CustomDestinationDataProvider test = new CustomDestinationDataProvider();//set properties for the destination and ...myProvider.changeProperties(destName, getDestinationPropertiesFromUI());//... work with it//连接测试test.executeCalls(destName);}}

然后可以用如下的代码来 call rfc。

import java.util.concurrent.CountDownLatch;import com.sap.conn.jco.*;import static com.chunqiu.modules.sap.CustomDestinationDataProvider.getDestinationPropertiesFromUI;/*** basic examples for Java to ABAP communication* qj*/
public class StepClient
{static String ABAP_AS = "ABAP_AS";static String ABAP_AS_POOLED = "ABAP_AS";static String ABAP_MS = "ABAP_AS";/*** This example demonstrates the destination concept introduced with JCO 3.* The application does not deal with single connections anymore. Instead* it works with logical destinations like ABAP_AS and ABAP_MS which separates* the application logic from technical configuration.* 测试连接* @throws JCoException*/public static void step1Connect() throws JCoException{JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS);System.out.println("Attributes:");System.out.println(destination.getAttributes());System.out.println();destination = JCoDestinationManager.getDestination(ABAP_MS);System.out.println("Attributes:");System.out.println(destination.getAttributes());System.out.println();}/*** This example uses a connection pool. However, the implementation of* the application logic is still the same. Creation of pools and pool management* are handled by the JCo runtime.* 使用连接池连接* @throws JCoException*/public static void step2ConnectUsingPool() throws JCoException{JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);destination.ping();System.out.println("Attributes:");System.out.println(destination.getAttributes());System.out.println();}/*** The following example executes a simple RFC function STFC_CONNECTION.* In contrast to JCo 2 you do not need to take care of repository management.* JCo 3 manages the repository caches internally and shares the available* function metadata as much as possible.* 使用getExportParameterList() 设置参数* @throws JCoException*/public static void step3SimpleCall() throws JCoException{//JCoDestination is the logic address of an ABAP system and ...JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);// ... it always has a reference to a metadata repository//从对象仓库中获取 RFM 函数JCoFunction function = destination.getRepository().getFunctionTemplate("ZFM_FI_TAXPLATFORM_PRICE").getFunction();System.out.println("function================="+function);if(function == null)throw new RuntimeException("ZFM_FI_TAXPLATFORM_PRICE not found in SAP.");//JCoFunction is container for function values. Each function contains separate//containers for import, export, changing and table parameters.//To set or get the parameters use the APIS setValue() and getXXX().// 设置import 参数JCoParameterList importParam = function.getExportParameterList();importParam.setValue("ZFIS_MBLNR", "123456789");try{//execute, i.e. send the function to the ABAP system addressed//by the specified destination, which then returns the function result.//All necessary conversions between Java and ABAP data types//are done automatically.function.execute(destination);}catch(AbapException e){//System.out.println(e.toString());return;}System.out.println("STFC_CONNECTION finished:");System.out.println(" Echo: " + function.getExportParameterList().getString("ECHOTEXT"));System.out.println(" Response: " + function.getExportParameterList().getString("RESPTEXT"));System.out.println();}/*** ABAP APIs often uses complex parameters. This example demonstrates  访问结构 (Structure)* how to read the values from a structure.* 构造访问* @throws JCoException*/public static void step3WorkWithStructure() throws JCoException{JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);JCoFunction function = destination.getRepository().getFunctionTemplate("ZFM_FI_TAXPLATFORM_PRICE").getFunction();if(function == null)throw new RuntimeException("ZFM_FI_TAXPLATFORM_PRICE not found in SAP.");try{function.execute(destination);}catch(AbapException e){System.out.println(e.toString());return;}//从返回数据中解析JCoStructure exportStructure = function.getExportParameterList().getStructure("RFCSI_EXPORT");System.out.println("System info for " + destination.getAttributes().getSystemID() + ":\n");//*********也可直接通过结构中的字段名或字段所在的索引位置来读取某个字段的值System.out.println("RFCPROTO:\t"+exportStructure.getString(0));System.out.println("RFCPROTO:\t"+exportStructure.getString("RFCPROTO"));//The structure contains some fields. The loop just prints out each field with its name.for(int i = 0; i < exportStructure.getMetaData().getFieldCount(); i++){System.out.println(exportStructure.getMetaData().getName(i) + ":\t" + exportStructure.getString(i));}System.out.println();//JCo still supports the JCoFields, but direct access via getXXX is more efficient as field iterator// efficient as field iterator  也可以使用下面的方式来遍历System.out.println("The same using field iterator: \nSystem info for " + destination.getAttributes().getSystemID() + ":\n");for(JCoField field : exportStructure){System.out.println(field.getName() + ":\t" + field.getString());}System.out.println();}/*** A slightly more complex example than before. Query the companies list   访问表* returned in a table and then obtain more details for each company.* 表结构访问* @throws JCoException*/public static void step4WorkWithTable() throws JCoException{JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);JCoFunction function = destination.getRepository().getFunction("ZFM_FI_TAXPLATFORM_PRICE");if(function == null)throw new RuntimeException("ZFM_FI_TAXPLATFORM_PRICE not found in SAP.");try{function.execute(destination);}catch(AbapException e){System.out.println(e.toString());return;}JCoStructure returnStructure = function.getExportParameterList().getStructure("RETURN");if (! (returnStructure.getString("TYPE").equals("")||returnStructure.getString("TYPE").equals("S"))  ){throw new RuntimeException(returnStructure.getString("MESSAGE"));}JCoTable codes = function.getTableParameterList().getTable("COMPANYCODE_LIST");for (int i = 0; i < codes.getNumRows(); i++){codes.setRow(i);System.out.println(codes.getString("COMP_CODE") + '\t' + codes.getString("COMP_NAME"));}//move the table cursor to first rowcodes.firstRow();for (int i = 0; i < codes.getNumRows(); i++, codes.nextRow()){function = destination.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");if (function == null)throw new RuntimeException("BAPI_COMPANYCODE_GETDETAIL not found in SAP.");function.getImportParameterList().setValue("COMPANYCODEID", codes.getString("COMP_CODE"));//We do not need the addresses, so set the corresponding parameter to inactive.//Inactive parameters will be  either not generated or at least converted.function.getExportParameterList().setActive("COMPANYCODE_ADDRESS",false);try{function.execute(destination);}catch (AbapException e){System.out.println(e.toString());return;}returnStructure = function.getExportParameterList().getStructure("RETURN");if (! (returnStructure.getString("TYPE").equals("") ||returnStructure.getString("TYPE").equals("S") ||returnStructure.getString("TYPE").equals("W")) ){throw new RuntimeException(returnStructure.getString("MESSAGE"));}JCoStructure detail = function.getExportParameterList().getStructure("COMPANYCODE_DETAIL");System.out.println(detail.getString("COMP_CODE") + '\t' +detail.getString("COUNTRY") + '\t' +detail.getString("CITY"));}//for}/*** this example shows the "simple" stateful call sequence. Since all calls belonging to one* session are executed within the same thread, the application does not need* to take into account the SessionReferenceProvider. MultithreadedExample.java* illustrates the more complex scenario, where the calls belonging to one session are* executed in different threads.** Note: this example uses Z_GET_COUNTER and Z_INCREMENT_COUNTER. Most ABAP systems* contain function modules GET_COUNTER and INCREMENT_COUNTER that are not remote-enabled.* Copy these functions to Z_GET_COUNTER and Z_INCREMENT_COUNTER (or implement as wrapper)* and declare them to be remote enabled.* 多线程 构造访问* @throws JCoException*/public static void step4SimpleStatefulCalls() throws JCoException{final JCoFunctionTemplate incrementCounterTemplate, getCounterTemplate;JCoDestination destination = JCoDestinationManager.getDestination(ABAP_MS);incrementCounterTemplate = destination.getRepository().getFunctionTemplate("Z_INCREMENT_COUNTER");getCounterTemplate = destination.getRepository().getFunctionTemplate("Z_GET_COUNTER");if(incrementCounterTemplate == null || getCounterTemplate == null)throw new RuntimeException("This example cannot run without Z_INCREMENT_COUNTER and Z_GET_COUNTER functions");final int threadCount = 5;final int loops = 5;final CountDownLatch startSignal = new CountDownLatch(threadCount);final CountDownLatch doneSignal = new CountDownLatch(threadCount);Runnable worker = new Runnable(){public void run(){startSignal.countDown();try{//wait for other threadsstartSignal.await();JCoDestination dest = JCoDestinationManager.getDestination(ABAP_MS);JCoContext.begin(dest);try{for(int i=0; i < loops; i++){JCoFunction incrementCounter = incrementCounterTemplate.getFunction();incrementCounter.execute(dest);}JCoFunction getCounter = getCounterTemplate.getFunction();getCounter.execute(dest);int remoteCounter = getCounter.getExportParameterList().getInt("GET_VALUE");System.out.println("Thread-" + Thread.currentThread().getId() +" finished. Remote counter has " + (loops==remoteCounter?"correct":"wrong") +" value [" + remoteCounter + "]");}finally{JCoContext.end(dest);}}catch(Exception e){System.out.println("Thread-" + Thread.currentThread().getId() + " ends with exception " + e.toString());}doneSignal.countDown();}};for(int i = 0; i < threadCount; i++){new Thread(worker).start();}try{doneSignal.await();}catch(Exception e){}}/*** 内表结构访问* @throws JCoException*/public static void rfcCall() throws JCoException{//JCoDestination is the logic address of an ABAP system and ...JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);// ... it always has a reference to a metadata repository//从对象仓库中获取 RFM 函数JCoFunction function = destination.getRepository().getFunctionTemplate("ZFM_FI_TAXPLATFORM_PRICE").getFunction();if(function == null)throw new RuntimeException("ZFM_FI_TAXPLATFORM_PRICE not found in SAP.");try {//如果传如参数是内表的形式的话就以如下代码传入sap系统JCoTable T_ACCDOCUMENT = function.getTableParameterList().getTable("IT_MBLNR");T_ACCDOCUMENT.appendRow();//增加一行//给表参数中的字段赋值,此处测试,就随便传两个值进去T_ACCDOCUMENT.setValue("MBLNR", "5001916414");//执行调用函数function.execute(destination);//获取传入参数返回状态表JCoTable statusTable = function.getTableParameterList().getTable("IT_MBLNR");//得到sap返回的参数,你就把他当作c语言的结构体理解就可以了for(int i = 0; i < statusTable.getNumRows(); i++) {statusTable.setRow(i);//这里获取sap函数传出内表结构的字段String rc = statusTable.getString("RCODE");String mblnr= statusTable.getString("MBLNR");//物料凭证编号 记住这里MBLNR一定是大写的,不然得不到值if(("02").equals(rc)){System.out.println("物料凭证编号:"+mblnr+"  合同编号未维护");}else if(("03").equals(rc)){System.out.println("物料凭证编号:"+mblnr+"  付款条件为空或不一致");}else if(("04").equals(rc)){System.out.println("物料凭证编号:"+mblnr+"  质检未通过");}else if(("05").equals(rc)){System.out.println("物料凭证编号:"+mblnr+"  物料凭证已被冲销");}else if(("06").equals(rc)){System.out.println("物料凭证编号:"+mblnr+"  物料凭证移动类型有误");}else if(("07").equals(rc)){System.out.println("物料凭证编号:"+mblnr+"  物料凭证移动不存在");}else {JCoTable exportTable = function.getTableParameterList().getTable("ET_DATA");//得到sap返回的参数,你就把他当作c语言的结构体理解就可以了System.out.println(exportTable);//有时候sap那边只是返回一个输出参数,sap比方说你这边输入一个物料号,想得到sap那边的物料描述,这是sap方是不会返回一个内表给你的//而是只是返回一个输出参数给你这时你就要用到下面的方法来得到输出参数//paramList = function.getExportParameterList();//paramList.getString("rfc返回字段字段名称");for(int j = 0; j < exportTable.getNumRows(); j++) {exportTable.setRow(i);//这里获取sap函数传出内表结构的字段String BUKRS = exportTable.getString("BUKRS");//记住这里BUKRS一定是大写的,不然得不到值System.out.println("公司代码<<<<<<<<<<<<<<<"+BUKRS);String LIFNR = exportTable.getString("LIFNR");System.out.println("供应商编号<<<<<<<<<<<<<<<"+LIFNR);String NAME1 = exportTable.getString("NAME1");System.out.println("供应商全称<<<<<<<<<<<<<<<"+NAME1);String SORTL = exportTable.getString("SORTL");System.out.println("供应商简称<<<<<<<<<<<<<<<"+SORTL);//得到了sap数据,然后下面就是你java擅长的部分了,想封装成什么类型的都由你}}}} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();} finally {destination = null;}}public static void main(String[] args) throws JCoException{//建立连接CustomDestinationDataProvider.MyDestinationDataProvider myProvider = new CustomDestinationDataProvider.MyDestinationDataProvider();//register the provider with the JCo environment;//catch IllegalStateException if an instance is already registeredtry{com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);}catch(IllegalStateException providerAlreadyRegisteredException){//somebody else registered its implementation,//stop the executionthrow new Error(providerAlreadyRegisteredException);}String destName = "ABAP_AS";CustomDestinationDataProvider test = new CustomDestinationDataProvider();//set properties for the destination and ...myProvider.changeProperties(destName, getDestinationPropertiesFromUI());//... work with ittest.executeCalls(destName);//step1Connect();//step2ConnectUsingPool();//step3SimpleCall();//step3WorkWithStructure();//step4WorkWithTable();//step4SimpleStatefulCalls();//测试访问rfcCall();}
}

测试结果

java使用Jco连接SAP相关推荐

  1. Java使用Jco连接sap详解

    SAP的R/3系统与Java平台一样有着许多类似的技术理念,以及同样广泛的企业级用户,但是它们完全是两个不同的世界.当用户面临流程 或者数据整合方面的需求的时候,就迫切需要一种高效的方式,在R/3系统 ...

  2. JAVA使用JCo连接SAP介绍

    SAP Java Connector (SAP JCo) 是JAVA与SAP相互通信的中间件组建.该组建支持双向通讯模式(inbound calls 和 outbound calls ). JCo支持 ...

  3. JAVA通过JCO连接SAP例子

    1.把librfc32.dll,sapjcorfc.dll 放到服务器的系统的c:\windows\system32目錄下 (不然会报错:sap Field IT_TABLnot a member o ...

  4. java使用jco连接sap调用rfc函数,环境配置+代码

    Windows环境配置 1.将sapjco3.jar引入 2.配置sapjco3.dll文件 32位系统:将sapjco3.dll放到C:\Windows\System32下  或者放到jdk/bin ...

  5. JCO连接SAP例子

    JCO连接SAP例子 SAP JCo(SAP Java Connector,SAP Java连接器)是SAP组件和Java应用程序之间的中间件和接口实现机制. JCo基于JNI(Java Native ...

  6. java使用JCO调用SAP接口

    博客参考:http://blog.csdn.net/jay_1989/article/details/51821069 (可以说我是基本照抄,所以本篇博客为转载) 其实在写这篇博客之前,已经有很多前辈 ...

  7. java jco连接sap帐号权限设定,Java连接SAP的JCO调用RFC配置

    第一步:下载librfc32.dll和sapjcorfc.dll文件,版本分别为6405.5.132.5092 - 6400.132.12.49905 第二步:将下载的两个DLL文件放在的window ...

  8. pajek软件使用方法_使用Jco远程连接SAP软件系统方法

    作者:JongWill声明:本文章仅用于SAP软件的应用与学习,不代表SAP公司.(注:文中所示截图来源SAP软件,相应著作权归SAP所有.)SAP公司的ERP系统是一套成熟的套装软件,它是博大精深的 ...

  9. SAP Java Connector(JCo)

    SAP Java Connector(JCo)      JCo是一个高性能的,基于JNI的中间件,它实现了SAP的RFC(Remote Function Call)协议. 1.JCo的安装 从 ht ...

  10. [SAP]JCO连接错误配置日志之无路由

    当连接SAP时,有防火墙且需要配置Router信息(DestinationDataProvider.JCO_SAPROUTER ,jco.client.saprouter),而没有配置,将报如下错误: ...

最新文章

  1. 匿名黑客Anonymous实施的8次最强攻击
  2. 图像色彩空间与应用转换
  3. android cts 编译,使用 Android studio 分析运行 CTS 用例
  4. 表头大小设置_Excel技巧:单线表头及多线表头的制作方法
  5. php服务器怎么设置cookie,php服务器如何清除浏览器cookie
  6. python计算最大回撤_最大回撤线性算法实现
  7. 直播间越播越没人,大部分刚开始做直播电商的人都会这样
  8. 2018年6月26日笔记
  9. Java 混淆那些事(五):ProGuard 其他的选项
  10. SQL 对大小写不敏感!
  11. CSS和JS标签style属性对照表
  12. 云服务器下行_阿里云ECS服务器下行带宽和上行带宽详解及选择
  13. retrofit介绍
  14. 14.VRP介绍以及AC初始化配置_AC和AP的软件升级方法
  15. 编程的名言名句(幽默版)
  16. 网络带宽和下载速度的换算
  17. Windows下架设自己的DNS服务器
  18. Jquery 模糊匹配ID
  19. android音频文件存放目录,Android系统声音文件目录
  20. arm+linux+usb驱动开发,Linux+ARM下的USB驱动开发

热门文章

  1. 二叉树的前中后序遍历
  2. 基于Python实现身份证号码验证
  3. PLC Outstudio 使用教程
  4. 2021 Namomo Summer Camp Day2 图论(杜瑜皓)
  5. iOS-调用系统的短信和发送邮件功能,实现短信分享邮件分享
  6. VB6.0 组织json对象并生成json字符串
  7. 项目案例:浙江宁波江北区道路照明智慧化改造见成效
  8. 离散数学及其应用(第六版) 习题
  9. 杭电ACM2030题
  10. java运行方法_java程序怎么运行?java程序运行方法