JAVA通過JCo連接SAP


關於JCo

SAP Java Connector (SAP JCo) 是JAVA與SAP相互通信的中間件組建。該組建支持雙向通訊模式(inbound calls  和 outbound calls )。

JCo支持Connection Pools和Direct兩種方式的連接。直接連接需要開發者來控制連接的創建和釋放,使用連接池方式可以讓池來管理連接的分配、管理和釋放,可以最大限度的節省系統開銷,相比直接方式優勢也是明顯的。本文的示例也是使用池方式連接。

安裝JCo

https://service.sap.com/connectors 下載3.0 或 2.1版本的JCo(需要 SAP Service MarketPlace賬號),至於用32bit的還是64bit的要根據你的JVM來選擇。

怎么查看自己的JVM版本?

-cmd 用 java -version
32位:Java HotSpot(TM) Client VM ....
64位:Java HotSpot(TM) 64-Bit Server VM ....
-或System.out.println("JVM Bit size: " + System.getProperty("sun.arch.data.model"));
-或System.out.println("JVM Bit size: " + System.getProperty("os.arch"));

1。 ZIP包解壓到一個目錄(像我,如果只是開發Web App,可以選擇不安裝的。。直接把sapjco3.dll和sapjco3.jar丟到lib目錄中就可以了

2。在PATH環境變量中指定JCo的安裝目錄

3。CLASSPASS 指定 安裝目錄\sapjco3.jar

打開 cmd 到安裝目錄 執行java -jar sapjco3.jar,安裝成功你可以看到如下的信息。。

注:  你也可以把sapjco3.dll丟進system32或SysWOW64目錄,這樣做就不用設置環境變量了,不過SAP官方不建議你這么做。。

解壓目錄中的javadoc,examples文件夾里面有一些簡單示例和文檔供參考。

JCo的使用

用JCo3做開發的時候都會涉及到Destination。在運行時,這個Destination會從 DestinationDataProvider 或 ServerDataProvider的實現類中獲取server addr. 和 logon info等相關信息。之后我們通過它來找到相應的RFC。下面是用來注冊 DestinationDataProvider的工具類。

 

import java.util.HashMap;
import java.util.Properties;

import com.sap.conn.jco.ext.DataProviderException;
import com.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;

public class JCOProvider implements DestinationDataProvider {

    private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
    private DestinationDataEventListener eL;

    @Override
    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);
        }
    }

    @Override
    public void setDestinationDataEventListener(
            DestinationDataEventListener eventListener) {
        this.eL = eventListener;

    }

    @Override
    public boolean supportsEvents() {
        return true;
    }

    //implementation that saves the properties in a very secure way
    public void changePropertiesForABAP_AS(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
            }
        }
    }
}

 

 

再創建一個RfcManager的類,用來讀取src目錄下的sap_conf.properties 來注冊Provider,獲取RFC Function和執行execute()方法。

sap_conf.properties

 

#Thu Nov 01 11:17:09 KST 2012
jco.client.ashost=***********
jco.client.client=300
jco.client.langu=KO
jco.client.passwd=password
jco.client.sysnr=02
jco.client.user=ABAP-01

 

 

 RfcManager.java

import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.ext.Environment;
import com.shany.common.util.StringUtil;

public final class RfcManager {
    private static Logger logger = Logger.getLogger(RfcManager.class);

    private static String ABAP_AS_POOLED = "XXX";

    private static JCOProvider provider = null;

    private static JCoDestination destination = null;

    static {
        Properties properties = loadProperties();

        provider = new JCOProvider();

        // catch IllegalStateException if an instance is already registered
        try {
            Environment.registerDestinationDataProvider(provider);
        } catch (IllegalStateException e) {
            logger.debug(e);
        }

        provider.changePropertiesForABAP_AS(ABAP_AS_POOLED, properties);
    }

    public static Properties loadProperties() {
        RfcManager manager = new RfcManager();
        Properties prop = new Properties();
        try {
            prop.load(manager.getClass().getResourceAsStream(
                    "/sap_conf.properties"));
        } catch (IOException e) {
            logger.debug(e);
        }
        return prop;
    }

    public static JCoDestination getDestination() throws JCoException {
        if (destination == null) {
            destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
        }
        return destination;
    }

    public static JCoFunction getFunction(String functionName) {
        JCoFunction function = null;
        try {
            function = getDestination().getRepository()
                    .getFunctionTemplate(functionName).getFunction();
        } catch (JCoException e) {
            logger.error(e);
        } catch (NullPointerException e) {
            logger.error(e);
        }
        return function;
    }

    public static void execute(JCoFunction function) {
        logger.debug("SAP Function Name : " + function.getName());
        JCoParameterList paramList = function.getImportParameterList();

        if (paramList != null) {
            logger.debug("Function Import Structure : " + paramList.toString());
        }

        try {
            function.execute(getDestination());
        } catch (JCoException e) {
            logger.error(e);
        }
        paramList = function.getExportParameterList();

        if (paramList != null) {
            logger.debug("Function Export Structure : " + paramList.toString());
        }
    }

    /*
     * SAP 연결 Ping 테스트
     */
    public static String ping() {
        String msg = null;
        try {
            getDestination().ping();
            msg = "Destination " + ABAP_AS_POOLED + " is ok";
        } catch (JCoException ex) {
            msg = StringUtil.getExceptionTrace(ex);
        }
        logger.debug(msg);
        return msg;
    }

    public static void main(String[] args) {
        RfcManager.ping();
    }
}

 

然后可以用如下的代碼來 call rfc.

public void callRfcExample() {
        // 獲取RFC 對象
        JCoFunction function = RfcManager.getFunction("function_name");
        // 設置import 參數
        JCoParameterList importParam = function.getImportParameterList();
        importParam.setValue("field_name", "val");
        // 執行RFC
        RfcManager.execute(function);

        // 獲取RFC返回的字段值
        JCoParameterList exportParam = function.getExportParameterList();
        String exParamA = exportParam.getString("field_A");
        String exParamB = exportParam.getString("field_B");
        // 遍歷RFC返回的表對象
        JCoTable tb = function.getTableParameterList().getTable("table_name");
        for (int i = 0; i < tb.getNumRows(); i++) {
            tb.setRow(i);
            System.out.println(tb.getString("field01"));
            System.out.println(tb.getString("field02"));
        }
    }

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM