溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

java怎么使用Jco連接SAP

發(fā)布時(shí)間:2023-03-22 13:57:29 來(lái)源:億速云 閱讀:151 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇“java怎么使用Jco連接SAP”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“java怎么使用Jco連接SAP”文章吧。

java使用Jco連接SAP

JCO為我們提供了另外一種連接的方法:

DestinationDataProvider,通過(guò)它我們就可以將一個(gè)連接變量信息存放在內(nèi)存里。

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>();
 
        // 實(shí)現(xiàn)接口:獲取連接配置屬性
        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");
        }
    }
 
    /**
     * 配置連接信息
     * @return
     */
    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");               //系統(tǒng)編號(hào)
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "620");              //客戶(hù)端編號(hào)
        connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "user");             //用戶(hù)名
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "123456");           //密碼
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "ZH");               //語(yǔ)言
        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
        //連接測(cè)試
        test.executeCalls(destName);
    }
 
}

然后可以用如下的代碼來(lái) 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.
     * 測(cè)試連接
     * @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() 設(shè)置參數(shù)
     * @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
        //從對(duì)象倉(cāng)庫(kù)中獲取 RFM 函數(shù)
        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().
        // 設(shè)置import 參數(shù)
        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  訪(fǎng)問(wèn)結(jié)構(gòu) (Structure)
     * how to read the values from a structure.
     * 構(gòu)造訪(fǎng)問(wèn)
     * @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;
        }
 
        //從返回?cái)?shù)據(jù)中解析
        JCoStructure exportStructure = function.getExportParameterList().getStructure("RFCSI_EXPORT");
        System.out.println("System info for " + destination.getAttributes().getSystemID() + ":\n");
 
        //*********也可直接通過(guò)結(jié)構(gòu)中的字段名或字段所在的索引位置來(lái)讀取某個(gè)字段的值
        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  也可以使用下面的方式來(lái)遍歷
        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   訪(fǎng)問(wèn)表
     * returned in a table and then obtain more details for each company.
     * 表結(jié)構(gòu)訪(fǎng)問(wèn)
     * @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 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
    }
 
    /**
     * 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.
     * 多線(xiàn)程 構(gòu)造訪(fǎng)問(wèn)
     * @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 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)
        {
        }
 
    }
 
 
    /**
     * 內(nèi)表結(jié)構(gòu)訪(fǎng)問(wèn)
     * @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
        //從對(duì)象倉(cāng)庫(kù)中獲取 RFM 函數(shù)
        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 {
             //如果傳如參數(shù)是內(nèi)表的形式的話(huà)就以如下代碼傳入sap系統(tǒng)
            JCoTable T_ACCDOCUMENT = function.getTableParameterList().getTable("IT_MBLNR");
            T_ACCDOCUMENT.appendRow();//增加一行
            //給表參數(shù)中的字段賦值,此處測(cè)試,就隨便傳兩個(gè)值進(jìn)去
            T_ACCDOCUMENT.setValue("MBLNR", "5001916414");
            //執(zhí)行調(diào)用函數(shù)
            function.execute(destination);
            //獲取傳入?yún)?shù)返回狀態(tài)表
            JCoTable statusTable = function.getTableParameterList().getTable("IT_MBLNR");//得到sap返回的參數(shù),你就把他當(dāng)作c語(yǔ)言的結(jié)構(gòu)體理解就可以了
 
            for(int i = 0; i < statusTable.getNumRows(); i++) {
                statusTable.setRow(i);
                //這里獲取sap函數(shù)傳出內(nèi)表結(jié)構(gòu)的字段
                String rc = statusTable.getString("RCODE");
                String mblnr= statusTable.getString("MBLNR");//物料憑證編號(hào) 記住這里MBLNR一定是大寫(xiě)的,不然得不到值
               if(("02").equals(rc)){
                    System.out.println("物料憑證編號(hào):"+mblnr+"  合同編號(hào)未維護(hù)");
                }else if(("03").equals(rc)){
                    System.out.println("物料憑證編號(hào):"+mblnr+"  付款條件為空或不一致");
                }else if(("04").equals(rc)){
                    System.out.println("物料憑證編號(hào):"+mblnr+"  質(zhì)檢未通過(guò)");
                }else if(("05").equals(rc)){
                    System.out.println("物料憑證編號(hào):"+mblnr+"  物料憑證已被沖銷(xiāo)");
                }else if(("06").equals(rc)){
                    System.out.println("物料憑證編號(hào):"+mblnr+"  物料憑證移動(dòng)類(lèi)型有誤");
                }else if(("07").equals(rc)){
                    System.out.println("物料憑證編號(hào):"+mblnr+"  物料憑證移動(dòng)不存在");
                }else {
                    JCoTable exportTable = function.getTableParameterList().getTable("ET_DATA");//得到sap返回的參數(shù),你就把他當(dāng)作c語(yǔ)言的結(jié)構(gòu)體理解就可以了
                   System.out.println(exportTable);
                    //有時(shí)候sap那邊只是返回一個(gè)輸出參數(shù),sap比方說(shuō)你這邊輸入一個(gè)物料號(hào),想得到sap那邊的物料描述,這是sap方是不會(huì)返回一個(gè)內(nèi)表給你的
                    //而是只是返回一個(gè)輸出參數(shù)給你這時(shí)你就要用到下面的方法來(lái)得到輸出參數(shù)
                    //paramList = function.getExportParameterList();
                    //paramList.getString("rfc返回字段字段名稱(chēng)");
                    for(int j = 0; j < exportTable.getNumRows(); j++) {
                        exportTable.setRow(i);
                        //這里獲取sap函數(shù)傳出內(nèi)表結(jié)構(gòu)的字段
                        String BUKRS = exportTable.getString("BUKRS");//記住這里BUKRS一定是大寫(xiě)的,不然得不到值
                        System.out.println("公司代碼<<<<<<<<<<<<<<<"+BUKRS);
 
                        String LIFNR = exportTable.getString("LIFNR");
                        System.out.println("供應(yīng)商編號(hào)<<<<<<<<<<<<<<<"+LIFNR);
 
                        String NAME1 = exportTable.getString("NAME1");
                        System.out.println("供應(yīng)商全稱(chēng)<<<<<<<<<<<<<<<"+NAME1);
 
                        String SORTL = exportTable.getString("SORTL");
                        System.out.println("供應(yīng)商簡(jiǎn)稱(chēng)<<<<<<<<<<<<<<<"+SORTL);
 
                        //得到了sap數(shù)據(jù),然后下面就是你java擅長(zhǎng)的部分了,想封裝成什么類(lèi)型的都由你
                    }
                }
            }
 
 
 
        } 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();
        //測(cè)試訪(fǎng)問(wèn)
        rfcCall();
    }
}

測(cè)試結(jié)果

java怎么使用Jco連接SAP

以上就是關(guān)于“java怎么使用Jco連接SAP”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI