Java SAP Связь
Я должен подключиться к системе SAP R/3 из отдельного приложения Java, используя JCo3.0. Насколько я понимаю, есть 2 способа подключения к системе SAP:
JCo Client JCo Server Теперь мое приложение отправляет и получает данные из системы SAP. Нужно ли использовать JCo Client/Server?
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);
}
}
}
2 способа подключения к локальной системе SAP по протоколу RFC:
- Входящая RFC-связь (как RFC-клиент / Java вызывает ABAP)
- Исходящая RFC-связь (поскольку RFC-сервер / ABAP вызывает Java)
Для входящих RFC вам необходимо использовать JCoDestination
для выполнения удаленного функционального модуля на стороне ABAP. Для исходящих RFC вам необходимо зарегистрировать JCoServer
на шлюзе SAP, который затем будет получать входящие запросы со стороны ABAP для обработки удаленного функционального модуля на стороне Java. В обоих направлениях связи имеется запрос и, возможно, также ответ на этот запрос, поэтому поток данных обычно идет в обоих направлениях, независимо от того, выполняете ли вы входящий или исходящий обмен данными RFC. Входящий и исходящий просто различают, кто инициирует вызов RFC.