2

我必须使用 JCo3.0 从独立的 Java 应用程序连接到 SAP R/3 系统。据我了解,有两种方式可以连接 SAP 系统:

  • JCo 客户
  • JCo 服务器

现在我的应用程序从 SAP 系统发送和接收数据。我需要使用 JCo 客户端/服务器吗?

4

2 回答 2

1

使用 R3 和 sapjco3.jar 为我工作的解决方案如下:

package com.example.springsocial.sap;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.ext.DestinationDataProvider;

public class SAPrfc {
    static String   IP="192.168.1.1",
                    USER="userName",
                    PASSWORD="myPassword",
                    CLIENT="100",// Mandatory number
                    SYSNR="00", // instance number
                    LANG="es", // language (es or en)
                    DESTINATION_NAME = "SAPconnection";

    private static JCoDestination destination;
    private static JCoParameterList outputTableParameterList;
    private static Map<String, Object> inputParameter;

    private static JCoFunction function;
    public static String rfcName="";
    public static String tableName="";

    public SAPrfc() throws Exception {
        setConnection();
        initConnection();
        clearParameters();
    }

    public static void setConnection() {
        System.out.println("setConnection in SAPrfc class");
        Properties connectProperties = new Properties();
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST,   IP);
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,    SYSNR);
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT,   CLIENT);
        connectProperties.setProperty(DestinationDataProvider.JCO_USER,     USER);
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,   PASSWORD);
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG,     LANG);
        createDestinationDataFile(DESTINATION_NAME,connectProperties);
    }

    private static void createDestinationDataFile(String destinationName, Properties connectProperties){
        File destCfg = new File(destinationName+".jcoDestination");
        try{
            FileOutputStream fos = new FileOutputStream(destCfg, false);
            connectProperties.store(fos, "for tests only !");
            fos.close();
        }catch (Exception e){
            throw new RuntimeException("Unable to create the destination files", e);
        }
    }

    public static void initConnection() throws Exception {
        System.out.println("initConnection in SAPrfc class");
        destination = JCoDestinationManager.getDestination(DESTINATION_NAME);
        System.out.println("Attributes:");
        System.out.println(destination.getAttributes());
        System.out.println();
        destination.ping();
    } 

    public static void setRfcName(String rfcNameParam) {rfcName= rfcNameParam; };
    public static void setTableName(String tableNameParam) {tableName= tableNameParam; };

    public static JCoParameterList getOutputTableParamList() { return outputTableParameterList;};
    public static JCoTable getOutputTable() { return outputTableParameterList.getTable(tableName);};

    public static void clearParameters() { inputParameter= new HashMap<>(); };
    public static void addParameter(String paramName, Object paramValue) { inputParameter.put(paramName, paramValue); }
    public static void setParameters() {
        if (inputParameter!=null)
            for(Map.Entry<String, Object> entry : inputParameter.entrySet()) {
                function.getImportParameterList().setValue(entry.getKey(), entry.getValue());
            }
    }

    public static void executeRFC() throws Exception {
        if (rfcName.equals(""))
            throw new Exception("Es requerido el nombre de una RFC");

        destination = JCoDestinationManager.getDestination(DESTINATION_NAME);
        function = destination.getRepository().getFunction(rfcName);

        if (function == null)
            throw new RuntimeException("BAPI_COMPANYCODE_GETLIST not found in SAP.");

        setParameters();
        function.execute(destination);
        if (function.getExportParameterList().getFieldCount()==0) 
            throw new Exception("Error al obtener los datos");


        String resultado = function.getExportParameterList().getString("RESULTADO").toString();
        if (!resultado.equals("X"))// correct
            throw new Exception(function.getExportParameterList().getString("MENSAJE").toString());

        outputTableParameterList = function.getTableParameterList();
        setRfcName("");
        clearParameters();
    }

    public static void main(String[] args) {
        try {
            //RFC without parameters
            SAPrfc.setRfcName("ZMMF_CAT_ALMACENES");
            SAPrfc.clearParameters();
            SAPrfc.executeRFC();    
            SAPrfc.setTableName("TI_ALMACENES");
            JCoTable table = SAPrfc.getOutputTable();
            String WERKS,LGORT,LGOBE;
            for (int i = 0; i < table.getNumRows(); i++, table.nextRow()){
                 WERKS = table.getString("WERKS");
                 LGORT = table.getString("LGORT");
                 LGOBE = table.getString("LGOBE");
                 System.out.println("[" + i + "] - WERKS : "+WERKS+" LGORT: "+LGORT+" LGOBE: "+LGOBE );
            }

            //RFC with parameters
            SAPrfc.setRfcName("ZMMF_CAT_MATERIALES");
            SAPrfc.clearParameters();
            SAPrfc.addParameter("IWERKS", 2010);
            SAPrfc.executeRFC();    
            SAPrfc.setTableName("TI_MATERIALES");
            JCoTable table2 = SAPrfc.getOutputTable();
            String MATNR,MAKTX,DUN14,BISMT;
            for (int i = 0; i < table2.getNumRows(); i++, table2.nextRow()){
                 MATNR = table2.getString("MATNR");
                 MAKTX = table2.getString("MAKTX");
                 DUN14 = table2.getString("DUN14");
                 BISMT = table2.getString("BISMT");
                 System.out.println("[" + i + "] - MATNR : "+MATNR+" MAKTX: "+MAKTX+" DUN14: "+DUN14+" BISMT: "+BISMT );
            }

            //RFC without parameters
            SAPrfc.setRfcName("ZMMF_CAT_TIPO_MOV");
            SAPrfc.clearParameters();
            SAPrfc.executeRFC();    
            SAPrfc.setTableName("TI_TIPO_MOV");
            JCoTable table3 = SAPrfc.getOutputTable();
            String ACTION,DDTEXT;
            for (int i = 0; i < table3.getNumRows(); i++, table3.nextRow()){
                ACTION = table3.getString("ACTION");
                DDTEXT = table3.getString("DDTEXT");
                System.out.println("[" + i + "] - ACTION : "+ACTION+" DDTEXT: "+DDTEXT);
            }
        }catch (Exception ex) {
            System.out.println("Exception "+ex);
        }
    }       
}
于 2020-03-25T18:31:12.393 回答
1

通过 RFC 协议连接到 SAP 本地系统的两种方法是:

  1. 入站 RFC 通信(作为 RFC 客户端/Java 调用 ABAP)
  2. 出站 RFC 通信(作为 RFC 服务器/ABAP 调用 Java)

对于入站 RFC,您需要使用 aJCoDestination在 ABAP 端执行远程功能模块。对于出站 RFC,您需要JCoServer在 SAP 网关上注册一个,然后它将接收来自 ABAP 端的传入请求,以便在 Java 端处理远程功能模块。在两个通信方向上都有一个请求,并且可能还有对此请求的响应,因此数据流通常是双向的,无论您是在进行入站还是出站 RFC 通信。入站和出站只是区分发起 RFC 调用的人。

于 2018-11-27T16:09:16.900 回答