文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

java使用Jco连接SAP过程

2023-03-22 17:02

关注

java使用Jco连接SAP

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
{
    
    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 DB
                Properties p = secureDBStorage.get(destinationName);
 
                if(p!=null)
                {
                    //check if all is correct, for example
                    if(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 logic
    void 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");
        }
    }
 
    
    static Properties getDestinationPropertiesFromUI()
    {
        //adapt parameters in order to configure a valid destination
        Properties connectProperties = new Properties();
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "***********");  //IP
        connectProperties.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 registered
        try
        {
            com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
        }
        catch(IllegalStateException providerAlreadyRegisteredException)
        {
            //somebody else registered its implementation,
            //stop the execution
            throw 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;
 

public class StepClient
{
    static String ABAP_AS = "ABAP_AS";
    static String ABAP_AS_POOLED = "ABAP_AS";
    static String ABAP_MS = "ABAP_AS";
 
    
    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();
    }
 
    
    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();
    }
 
    
    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();
    }
 
    
    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");
 
        /
    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 row
        codes.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
    }
 
    
    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 threads
                    startSignal.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)
        {
        }
 
    }
 
 
    
    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 block
            e1.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 registered
        try
        {
            com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
        }
        catch(IllegalStateException providerAlreadyRegisteredException)
        {
            //somebody else registered its implementation,
            //stop the execution
            throw 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);
 
        //step1Connect();
        //step2ConnectUsingPool();
        //step3SimpleCall();
        //step3WorkWithStructure();
        //step4WorkWithTable();
        //step4SimpleStatefulCalls();
        //测试访问
        rfcCall();
    }
}

测试结果

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯