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 + "]";
	}
    
}

  

 

posted @ 2020-03-14 13:48  lynchfang  阅读(671)  评论(0)    收藏  举报