SAP Java 一级参数 二级参数表
测试代码
/**
* @see https://www.huihoo.org/openweb/jco_api/com/sap/mw/jco/JCO.Exception.html#JCO_ERROR_ILLEGAL_ARGUMENT
* @see https://www.cnblogs.com/hikarisama/p/10091253.html
* @see https://blog.csdn.net/qq_38284858/article/details/90053402
*/
public class TestSAPInterface {
public static void main(String[] args) throws Exception{
List<SapData> data = new MultiFromSAP()
.setInterfaceName("XX")
.setFirstParamValue("I_B_AUDAT", "2019-01-01")
.setFirstParamValue("I_E_AUDAT", "2019-01-10")
.setSecondParamValue("VKORG", "8110","XX",1)
.setSecondParamValue("VKORG", "8160","XX",2)
.getSapData();
System.out.println(data);
}
}
相关资源
链接:https://pan.baidu.com/s/1DexMVdDT4_mRtqCcnbFXTQ
提取码:0an3
一、连接配置
/**
* @author 920279419@qq.com
* @see
*
*/
public class SapConn {
// SAP服务器
private String JCO_ASHOST;
// SAP系统编号
private String JCO_SYSNR;
// SAP集团
private String JCO_CLIENT;
// SAP用户名
private String JCO_USER;
// SAP密码
private String JCO_PASSWD;
// SAP登录语言
private String JCO_LANG;
// 最大连接数
private String JCO_POOL_CAPACITY;
// 最大连接线程
private String JCO_PEAK_LIMIT;
// SAP ROUTER
private String JCO_SAPROUTER;
public SapConn(String JCO_ASHOST, String JCO_SYSNR, String JCO_CLIENT, String JCO_USER,
String JCO_PASSWD, String JCO_LANG, String JCO_POOL_CAPACITY, String JCO_PEAK_LIMIT,
String JCO_SAPROUTER) {
this.JCO_ASHOST = JCO_ASHOST;
this.JCO_SYSNR = JCO_SYSNR;
this.JCO_CLIENT = JCO_CLIENT;
this.JCO_USER = JCO_USER;
this.JCO_PASSWD = JCO_PASSWD;
this.JCO_LANG = JCO_LANG;
this.JCO_POOL_CAPACITY = JCO_POOL_CAPACITY;
this.JCO_PEAK_LIMIT = JCO_PEAK_LIMIT;
this.JCO_SAPROUTER = JCO_SAPROUTER;
}
public SapConn(){}
@Override
public String toString() {
return "SapConn{" +
"JCO_ASHOST='" + JCO_ASHOST + '\'' +
", JCO_SYSNR='" + JCO_SYSNR + '\'' +
", JCO_CLIENT='" + JCO_CLIENT + '\'' +
", JCO_USER='" + JCO_USER + '\'' +
", JCO_PASSWD='" + JCO_PASSWD + '\'' +
", JCO_LANG='" + JCO_LANG + '\'' +
", JCO_POOL_CAPACITY='" + JCO_POOL_CAPACITY + '\'' +
", JCO_PEAK_LIMIT='" + JCO_PEAK_LIMIT + '\'' +
", JCO_SAPROUTER='" + JCO_SAPROUTER + '\'' +
'}';
}
public void setJCO_ASHOST(String jCO_ASHOST) {
JCO_ASHOST = jCO_ASHOST;
}
public void setJCO_SYSNR(String jCO_SYSNR) {
JCO_SYSNR = jCO_SYSNR;
}
public void setJCO_CLIENT(String jCO_CLIENT) {
JCO_CLIENT = jCO_CLIENT;
}
public void setJCO_USER(String jCO_USER) {
JCO_USER = jCO_USER;
}
public void setJCO_PASSWD(String jCO_PASSWD) {
JCO_PASSWD = jCO_PASSWD;
}
public void setJCO_LANG(String jCO_LANG) {
JCO_LANG = jCO_LANG;
}
public void setJCO_POOL_CAPACITY(String jCO_POOL_CAPACITY) {
JCO_POOL_CAPACITY = jCO_POOL_CAPACITY;
}
public void setJCO_PEAK_LIMIT(String jCO_PEAK_LIMIT) {
JCO_PEAK_LIMIT = jCO_PEAK_LIMIT;
}
public void setJCO_SAPROUTER(String jCO_SAPROUTER) {
JCO_SAPROUTER = jCO_SAPROUTER;
}
public String getJCO_ASHOST() {
return JCO_ASHOST;
}
public String getJCO_SYSNR() {
return JCO_SYSNR;
}
public String getJCO_CLIENT() {
return JCO_CLIENT;
}
public String getJCO_USER() {
return JCO_USER;
}
public String getJCO_PASSWD() {
return JCO_PASSWD;
}
public String getJCO_LANG() {
return JCO_LANG;
}
public String getJCO_POOL_CAPACITY() {
return JCO_POOL_CAPACITY;
}
public String getJCO_PEAK_LIMIT() {
return JCO_PEAK_LIMIT;
}
public String getJCO_SAPROUTER() {
return JCO_SAPROUTER;
}
}
二、连接管理
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
/**
* @author 920279419@qq.com
* @see
*
*/
public class SAPConnUtils {
private static SapConn sapConn = new SapConn();
private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
public static JCoDestination buildConn(){
return connect();
}
static {
// 从配置文件中读取
sapConn.setJCO_ASHOST("xx");
sapConn.setJCO_SYSNR("xx");
sapConn.setJCO_CLIENT("xx");
sapConn.setJCO_USER("xx");
sapConn.setJCO_PASSWD("xx");
sapConn.setJCO_LANG("xx");
sapConn.setJCO_POOL_CAPACITY("xx");
sapConn.setJCO_PEAK_LIMIT("xx");
sapConn.setJCO_SAPROUTER("xx");
}
/**
* 创建SAP接口属性文件。
* @param name ABAP管道名称
* @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连接
*/
private static void initProperties() {
Properties connectProperties = new Properties();
// SAP服务器
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, sapConn.getJCO_ASHOST());
// SAP系统编号
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, sapConn.getJCO_SYSNR());
// SAP集团
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, sapConn.getJCO_CLIENT());
// SAP用户名
connectProperties.setProperty(DestinationDataProvider.JCO_USER, sapConn.getJCO_USER());
// SAP密码
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, sapConn.getJCO_PASSWD());
// SAP登录语言
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, sapConn.getJCO_LANG());
// 最大连接数
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, sapConn.getJCO_POOL_CAPACITY());
// 最大连接线程
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, sapConn.getJCO_PEAK_LIMIT());
// SAP ROUTER
//connectProperties.setProperty(DestinationDataProvider.JCO_SAPROUTER, sapConn.getJCO_SAPROUTER());
createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
}
/**
* 获取SAP连接
* @return SAP连接对象
*/
private static JCoDestination connect(){
JCoDestination destination = null;
initProperties();
try {
destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
destination.ping();
System.out.println("Connect SAP success!");
} catch (JCoException e) {
System.out.println("Connect SAP fault, error msg: " + e.toString());
}
return destination;
}
}
三、请求 / 解析
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoRecordMetaData;
import com.sap.conn.jco.JCoTable;
/**
* @author 920279419@qq.com
* @see
*
*/
public class MultiFromSAP {
private String interfaceName; //接口名称
// 一级查询参数
private Map<String,String> importParas = new HashMap<String, String>();
// 二级查询参数表
private Map<String,List<Map<String,String>>> talParas =
new HashMap<String,List<Map<String,String>>>();
// 返回表的名称
private List<String> retTabsName = new ArrayList<String>();
// 返回的数据存放池
@SuppressWarnings("rawtypes")
private List<SapData> dataPool = new ArrayList<SapData>();
public MultiFromSAP(){}
@SuppressWarnings("rawtypes")
public List<SapData> getSapData() throws Exception{
JCoFunction function;
JCoDestination destination = SAPConnUtils.buildConn();
System.out.println("read data from SAPConn......");
try {
// 调用interface函数
function = destination.getRepository().getFunction(interfaceName);
if (null == function)
throw new RuntimeException("not found interface : " + interfaceName);
function = initQueryParams(function);
function.execute(destination);
// 如果返回的二级参数是表
if(!retTabsName.isEmpty()){
getExportTables(function);
}
getExportParamsValue(function.getTableParameterList());
}catch (Exception e) {
e.printStackTrace();
}
return this.dataPool;
}
private void getExportParamsValue(JCoParameterList list) {
for (JCoField jCoField : list) {
JCoTable respsTable = jCoField.getTable();
// 获取metaData(包含表的关键信息)
JCoRecordMetaData metaData = respsTable.getRecordMetaData();
SapData<List<Map<String, Object>>> sapData = new SapData<List<Map<String, Object>>>();
// 获取总返回的列数
sapData.setFieldCount(metaData.getFieldCount());
// 获取&存放 全部列的名称
String[] names = new String[sapData.getFieldCount()];
for (int j = 0; j < sapData.getFieldCount(); ++j) {
names[j] = metaData.getName(j);
}
sapData.setFieldNames(names);
// 获取全部数据
List<Map<String, Object>> sapRetDataTable = new ArrayList<Map<String, Object>>();
for (int i = 0; i < respsTable.getNumRows(); ++i) {
// 取行
respsTable.setRow(i);
Map<String, Object> columnMap = new HashMap<String, Object>();
// 取列
for (String cellName : sapData.getFieldNames()) {
columnMap.put(cellName, respsTable.getValue(cellName));
}
sapRetDataTable.add(columnMap);
}
sapData.setData(sapRetDataTable);
this.dataPool.add(sapData);
}
}
private JCoFunction initQueryParams(JCoFunction function) {
// 设置import参数
for (Map.Entry<String, String> entry : this.importParas.entrySet()) {
function.getImportParameterList().setValue(entry.getKey(),
null == entry.getValue() ? "" : entry.getValue());
}
// 如果import有表,则设置表
for (Map.Entry<String, List<Map<String, String>>> entry : this.talParas.entrySet()) {
JCoTable tab = function.getTableParameterList().getTable(entry.getKey());
// 得到表
List<Map<String, String>> data = entry.getValue();
tab.appendRows(data.size());
for(int i = 0; i < data.size(); i++){
Map<String, String> rowMap = data.get(i);
tab.setRow(i);
// fill table cells
for (Map.Entry<String, String> cell : rowMap.entrySet()) {
tab.setValue(cell.getKey(), cell.getValue());
}
}
}
return function;
}
private void getExportTables(JCoFunction function) {
Map<String,List<Map<String,Object>>> retTabs =
new HashMap<String,List<Map<String,Object>>>();
SapData<Map<String,List<Map<String,Object>>>> exportTabs =
new SapData<Map<String,List<Map<String,Object>>>>();
// 存放返回表的名称
List<String> sapDataOfFieldNames = new ArrayList<String>();
// 表的个数
exportTabs.setFieldCount(0);
for(String talName : this.retTabsName){
JCoTable jcoTable = function.getTableParameterList().getTable(talName);
if(null == jcoTable) continue;
sapDataOfFieldNames.add(talName);
exportTabs.setFieldCount(1+exportTabs.getFieldCount());
// 要点说明:对JCoTable,输出表头和行项目。
// 表头通过获取JCoTable的JCoRecordMetaData,然后使用JCoRecordMetaData的getName()方法
// JCoRecordMetaData tableMeta =
// jcoTable.getRecordMetaData();
// for(int i = 0; i < tableMeta.getFieldCount(); i++){
// System.out.print(String.format("%s\t",
// tableMeta.getName(i)));
// }
// 获取表体
List<Map<String,Object>> tabBody = new ArrayList<Map<String,Object>>();
// JCoTable每一行都是一个JCoStructure,可以通过setRow()设置指针的位置,然后再遍历各个field:
for (int i = 0; i < jcoTable.getNumRows(); ++i) {
// Sets the row pointer to the specified
jcoTable.setRow(i);
Map<String,Object> rowMap = new HashMap<String,Object>();
for (JCoField cell : jcoTable)
rowMap.put(cell.getName(), cell.getValue());
tabBody.add(rowMap);
}
retTabs.put(talName, tabBody);
}
exportTabs.setFieldNames((String[])sapDataOfFieldNames.toArray());
exportTabs.setData(retTabs);
this.dataPool.add(exportTabs);
}
/**
* 根据{@tableName}构造二级参数查询表
*
* @param key
* @param value
* @param tableName 所在表
* @param rowsNum 所在表的第几行
* 当rowNum的值超过,table.size() 的时候,自动追加一行
* 如:setSecondParamValue("VKORG", "6110","XSMX",1) // 表示,将 "VKORG=6110",放在第一行
*
*/
public MultiFromSAP setSecondParamValue(String key, String value, String tableName, int rowsNum) {
if(null == key || null == value || null == tableName || rowsNum < 1 ) return this;
if(this.talParas.containsKey(tableName)){ //是否存在{@tableName}表
List<Map<String,String>> table = this.talParas.get(tableName); //
// 检查 tableName 表的 第 rowsNum 行是否存在,不存在,则追加一行
if(table.size() > rowsNum || table.size() == rowsNum){ //
Map<String,String> targetRow = table.get(rowsNum - 1);
if(targetRow.containsKey(key)){// 检查该行是否已经有该元素,没有,则放入,有则报错提醒
throw new RuntimeException("表 "+tableName+" 第 " + rowsNum + " 行已经存在该值。("+ targetRow.get(key) +")");
}else{
targetRow.put(key, value);
}
}else{
Map<String,String> newRow = new HashMap<String, String>();
newRow.put(key, value);
table.add(newRow);
}
}else{
Map<String,String> row = new HashMap<String, String>();
row.put(key, value);
List<Map<String,String>> table = new ArrayList<Map<String,String>>();
table.add(row);
this.talParas.put(tableName, table);
}
return this;
}
@SuppressWarnings("unchecked")
public MultiFromSAP willReturnBackTableNames(String...names){
if(null != names && names.length > 0)
this.retTabsName = Arrays.asList(names);
return this;
}
public String getInterfaceName() {
return interfaceName;
}
public MultiFromSAP setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
return this;
}
public MultiFromSAP setFirstParamValue(String key, String value) {
if(null == key || null == value) return this;
this.importParas.put(key, value);
return this;
}
}
四、数据暂存池
import java.util.Arrays;
/**
* @author 920279419@qq.com
* @see
*
*/
public class SapData<T> {
// 列数
private int fieldCount;
// 列的具体名称
private String[] fieldNames;
// 全部数据
private T data;
public int getFieldCount() {
return fieldCount;
}
public void setFieldCount(int fieldCount) {
this.fieldCount = fieldCount;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String[] getFieldNames() {
return fieldNames;
}
public void setFieldNames(String[] fieldNames) {
this.fieldNames = fieldNames;
}
@Override
public String toString() {
return "SapData [fieldCount=" + fieldCount + ", fieldNames="
+ Arrays.toString(fieldNames) + ", data=" + data + "]";
}
}

浙公网安备 33010602011771号