您好,登錄后才能下訂單哦!
這篇“java怎么使用Jco連接SAP”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“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(); } }
以上就是關(guān)于“java怎么使用Jco連接SAP”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(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)容。