Java連接SAP RFC實現(xiàn)數(shù)據抽取的示例詳解
包管理
首先要連接SAP需要兩個包,分別為sapjco3.jar和sapjco3.dll,切記這兩個包需要放在同一目錄;否則會報錯。
我先嘗試將這兩個包發(fā)到私服上,再在pom.xml文件中引入,發(fā)現(xiàn).dll文件下載不了;于是就將這兩個包放在根目錄sap下,dockerfile構建鏡像時將這兩個包copy到jdk/lib目錄下。
COPY sap/sapjco3.dll /usr/local/jdk-17.0.5/lib/ COPY sap/sapjco3.jar /usr/local/jdk-17.0.5/bin/
功能介紹
- 連接SAP
- 入參獲取
- 出參獲取
- 函數(shù)列表獲取
- 表名獲取
- 函數(shù)執(zhí)行
- 執(zhí)行結果獲取
Java連接SAP RFC
public class CheckSnFromSAP {
private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
public static void main(String[] args) {
JCoFunction function = null;
MyDestinationDataProvider destDataProvider = new MyDestinationDataProvider();
try {
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "xxx");// 服務器
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "xx"); // 系統(tǒng)編號
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx"); // SAP集團
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "xxx"); // SAP?戶名
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "xxx"); // 密碼
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ZH"); // 登錄語?:ZH EN
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3"); // 最?連接數(shù)
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10"); // 最?連接線程
// 注冊連接參數(shù)
destDataProvider.addDestination(ABAP_AS_POOLED, connectProperties);
Environment.registerDestinationDataProvider(destDataProvider);
// 創(chuàng)建一個與SAP系統(tǒng)的連接
JCoDestination destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
// 調用函數(shù)
function = destination.getRepository().getFunction("funcationName");
if(null == function) {
throw new RuntimeException("無此函數(shù)");
}
// 輸入字段
JCoListMetaData listMetaData = function.getImportParameterList().getListMetaData();
List<Map<String, String>> inputFields = new ArrayList<>();
for (int i=0; i< listMetaData.getFieldCount(); i++) {
Map<String, String> row = new HashMap<>();
String name = listMetaData.getName(i);
String type = listMetaData.getTypeAsString(i);
String sapType = listMetaData.getRecordTypeName(i);
String description = listMetaData.getDescription(i);
row.put("name", name);
row.put("type", type);
row.put("sapType", sapType);
row.put("description", description);
inputFields.add(row);
}
// 輸出字段
JCoTable output = function.getTableParameterList().getTable("XXX");
JCoRecordMetaData recordMetaData = output.getRecordMetaData();
List<Map<String, String>> outputFields = new ArrayList<>();
for (int i=0; i< recordMetaData.getFieldCount(); i++) {
Map<String, String> row = new HashMap<>();
String name = recordMetaData.getName(i);
String type = recordMetaData.getTypeAsString(i);
String sapType = recordMetaData.getRecordTypeName(i);
String description = recordMetaData.getDescription(i);
row.put("name", name);
row.put("type", type);
row.put("sapType", sapType);
row.put("description", description);
outputFields.add(row);
}
// 獲取所有函數(shù)
function = destination.getRepository().getFunction("RFC_FUNCTION_SEARCH");
if(null == function) {
throw new RuntimeException("無此函數(shù)");
}
JCoParameterList importParams = function.getImportParameterList();
importParams.setValue("FUNCNAME", "*"); // Search for all functions
function.execute(destination);
JCoTable functionTable = function.getTableParameterList().getTable("FUNCTIONS");
int max = Math.min(functionTable.getNumRows(),500);
for (int i = 0; i <max; i++) {
functionTable.setRow(i);
String functionName = functionTable.getString("FUNCNAME");
System.out.println("函數(shù)名:"+functionName);
}
//獲取所有表名
JCoParameterList tableParameterList = function.getTableParameterList();
if(tableParameterList!=null){
for (JCoField jCoField : tableParameterList) {
System.out.println("表:" + jCoField.getName());
}
}
// 輸?參數(shù)修改
JCoParameterList input = function.getImportParameterList();
input.setValue("I_END", "2017-05-01");
input.setValue("I_START", "2017-01-01");
// JCoTable it_matnr = function.getTableParameterList().getTable("XXX");//以表作為請求參數(shù)
// it_matnr.appendRow();
// it_matnr.setValue("age",18);//設置表值
//方法執(zhí)行
function.execute(destination);
// 函數(shù)執(zhí)行結果
JCoTable jcoTable = function.getTableParameterList().getTable("tableName");
int numRows = jcoTable.getNumRows();//行數(shù)為0可以直接return
for (int i = 0; i < numRows; i++) {
jcoTable.setRow(i);//設置索引 獲取返回表里的數(shù)據
String fieldValue= jcoTable.getString("fieldName");//解析表字段值
System.out.println(fieldValue);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 取消環(huán)境注冊
Environment.unregisterDestinationDataProvider(destDataProvider);
}
}
}/**
* 實現(xiàn)DestinationDataProvider接口,用于注冊連接參數(shù)
*/
class MyDestinationDataProvider implements DestinationDataProvider {
private DestinationDataEventListener eventListener;
private Map<String, Properties> destinationProperties;
public MyDestinationDataProvider() {
destinationProperties = new HashMap<>();
}
public void addDestination(String destinationName, Properties properties) {
destinationProperties.put(destinationName, properties);
}
@Override
public Properties getDestinationProperties(String destinationName) {
if (destinationProperties.containsKey(destinationName)) {
return destinationProperties.get(destinationName);
}
return null;
}
@Override
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eventListener = eventListener;
}
@Override
public boolean supportsEvents() {
return true;
}
}當然也可以通過創(chuàng)建文件的方式保存連接屬性
public class SapConnection {
private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
static {
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "xxx");// 服務器
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "xx"); // 系統(tǒng)編號
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx"); // SAP集團
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "xxx"); // SAP?戶名
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "xxx"); // 密碼
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "ZH"); // 登錄語?:ZH EN
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3"); // 最?連接數(shù)
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10"); // 最?連接線程
createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
}
/**
* 創(chuàng)建sap接口屬性文件
* @param name
* @param suffix
* @param properties
*/
private static void createDataFile(String name, String suffix, Properties properties) {
File cfg = new File(name + "." + suffix);
if (cfg.exists()) {
cfg.deleteOnExit();
}
try {
FileOutputStream fos = new FileOutputStream(cfg, false);
properties.store(fos, "for tests only !");
fos.close();
} catch (Exception e) {
System.out.println("Create Data file fault, error msg: " + e.toString());
throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
}
}
/**
* 獲取sap連接
* @return
*/
public static JCoDestination connect() {
JCoDestination destination = null;
try {
destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
} catch (JCoException e) {
System.out.println("Connect SAP fault, error msg: " + e.toString());
}
return destination;
}
}在使用場景中,我遇到了這樣一種情況:
SpringBoot服務已啟動,sap函數(shù)入參兩個,上面代碼獲取sap函數(shù)入參兩個; 我將sap函數(shù)入參改為三個后,上面代碼獲取還是兩個,重啟服務后獲取就是正確的三個了。
經過研究發(fā)現(xiàn),JCoDestinationManager.getDestination(ABAP_AS_POOLED);會緩存destination連接,每次都是先從緩存中取
RfcDestination destination = (RfcDestination)this.destinations.get(destinationName);
查看destination.getRepository()會發(fā)現(xiàn)storage字段緩存了function等信息;解決辦法是:
// 清除緩存 destination.getRepository().clear();
清除緩存后,每次會獲取新的內容。
到此這篇關于Java連接SAP RFC實現(xiàn)數(shù)據抽取的示例詳解的文章就介紹到這了,更多相關Java數(shù)據抽取內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java實現(xiàn)拉鉤網上的FizzBuzzWhizz問題示例
這篇文章主要介紹了java實現(xiàn)拉鉤網上的FizzBuzzWhizz問題示例,需要的朋友可以參考下2014-05-05
Spring配置文件解析之BeanDefinitionReader詳解
這篇文章主要介紹了Spring配置文件解析之BeanDefinitionReader詳解,ApplicationContext.xml配置文件解析成Document對象,真正對xml中元素解析的類是在BeanDefinitionDocumentReader的實現(xiàn)類中來完成的,需要的朋友可以參考下2024-02-02
如何使用Comparator比較接口實現(xiàn)ArrayList集合排序
這篇文章主要介紹了如何使用Comparator比較接口實現(xiàn)ArrayList集合排序問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
java如何執(zhí)行bat腳本,并監(jiān)控執(zhí)行結果
這篇文章主要介紹了java如何執(zhí)行bat腳本,并監(jiān)控執(zhí)行結果問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
Mybatis resultType返回結果為null的問題排查方式
這篇文章主要介紹了Mybatis resultType返回結果為null的問題排查方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

