我必须使用 JCo3.0 从独立的 Java 应用程序连接到 SAP R/3 系统。据我了解,有两种方式可以连接 SAP 系统:
- JCo 客户
- JCo 服务器
现在我的应用程序从 SAP 系统发送和接收数据。我需要使用 JCo 客户端/服务器吗?
使用 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);
}
}
}
通过 RFC 协议连接到 SAP 本地系统的两种方法是:
对于入站 RFC,您需要使用 aJCoDestination
在 ABAP 端执行远程功能模块。对于出站 RFC,您需要JCoServer
在 SAP 网关上注册一个,然后它将接收来自 ABAP 端的传入请求,以便在 Java 端处理远程功能模块。在两个通信方向上都有一个请求,并且可能还有对此请求的响应,因此数据流通常是双向的,无论您是在进行入站还是出站 RFC 通信。入站和出站只是区分发起 RFC 调用的人。