Java訪問SAP(RFC連接)接口

項目基於Spring 4.3.7 + Hibernate 4.3.11

1. 前端ajax調用

Z_PLM_SAP_CRM_MASTER接口前端調用

//根據項目編碼,獲取項目描述
function changeProjectCode1(that1) {
    var flag = '';
    var projectCode = $.trim($(that1).val());
    var sapCode = "QAS_800"; //sap客戶端
    var datas = [];
    $.ajax({
        url: '${pageContext.request.contextPath}/SD00001Controller/Z_PLM_SAP_CRM_MASTER.action',
        async: false,
        type: "POST",
        data: {
            projectCodeList: [projectCode], //後臺傳入參數爲list,則這裏需要爲數組
            sapCode: sapCode
        },
        dataType: "json", //返回結果,text爲字符串類型,json爲數組,集合類型
        success: function (data) {
            flag = true;
        }
    });
    return flag;
}

ZBPM_SD_CHECK_SALES_VIEW接口前端調用

//校驗物料主數據是否有拓展方法
function ZBPM_SD_CHECK_SALES_VIEW(rowgroup) {
    var msg = "";
    var MATNR =  $.trim($("#dynamicRowsId tr[rowgroup=" + rowgroup + "] [name^=material]").val());
    var VKORG =  $.trim($("#dynamicRowsId tr[rowgroup=" + rowgroup + "] [name^=salesOrganization]").val());
    var VTWEG =  $.trim($("#dynamicRowsId tr[rowgroup=" + rowgroup + "] [name^=distributionChannel]").val());
    var sapCode = ""; //sap客戶端
    var reg = /^(9[0-9]*)$/;
    if (reg.test(VKORG)) {
        sapCode = "QAS_900";
    } else {
        sapCode = "QAS_800";
    }
    $.ajax({
        url: ctx + '/SD00001Controller/ZBPM_SD_CHECK_SALES_VIEW.action',
        async: false,
        type: "POST",
        data: {
            MATNR: MATNR,
            VKORG: VKORG,
            VTWEG: VTWEG,
            sapCode: sapCode
        },
        dataType: "json", //返回結果,text爲字符串類型,json爲數組,集合類型
        success: function (data) {
            msg = data.msg;
        }
    });
    return msg;
}

ZBPM_SD_CREATE_SALES_PRICE接口前端調用

//銷售價格寫入SAP系統
function writeToSAP() {
    var msg = "";
    var rows_800 = [];
    var rows_900 = [];
    $("#dynamicRowsId tbody tr").each(function (i) {
      debugger;
        var MATNR =$.trim($(this).find("input[name^=material]").val()); //物料號
        var VKORG =$.trim($(this).find("input[name^=salesOrganization]").val()); //銷售組織
        var sapCode = ""; //sap客戶端
        if (VKORG.slice(0, 1) == "9") {
            sapCode = "QAS_900";
        } else {
            sapCode = "QAS_800";
        }
        var row = {
            MATNR: MATNR,
            VKORG: VKORG
        };
        if (sapCode == "QAS_800") {
            rows_800.push(row);
        } else if (sapCode == "QAS_900") {
            rows_900.push(row);
        }
    });
  
    if (rows_800.length > 0) {
        ZBPM_SD_CREATE_SALES_PRICE(rows_800, "QAS_800");
    }
    if (rows_900.length > 0) {
        ZBPM_SD_CREATE_SALES_PRICE(rows_900, "QAS_900");
    }
    return msg;
}

function ZBPM_SD_CREATE_SALES_PRICE(rows, sapCode) {
    $.ajax({
        url: ctx+'/SD00001Controller/ZBPM_SD_CREATE_SALES_PRICE.action',
        async: false,
        type: "POST",
        data: {
            CT_PRICE: JSON.stringify(rows),
            sapCode: sapCode
        },
        dataType: "json", //返回結果,text爲字符串類型,json爲數組,集合類型
        success: function (data) {
            if (data.result) {
                var rows = data.data;
                for (var i = 0; i < rows.length; i++) {
                    var row = rows[i];
                    var index = row.ITMNO;
                    $("#dynamicRowsId [name^=Exception]").eq(parseInt(index)-1).val(row.OKSTA + ";" + row.MSGTX);
                }
            }
        }
    });
 
}

2. 實現Controller層

控制層,用於向前端提供HTTP訪問接口,返回響應Json數據。

package com.gzsolartech.portal.controller.SD;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.gzsolartech.bpmportal.controller.wfController.SD0402Controller;
import com.gzsolartech.portal.service.SD.SD00001Service;
/* SD00001銷售價格自動創建 */
@Controller
@RequestMapping("/SD00001Controller")
public class SD00001Controller {
	@Autowired
	SD00001Service sd00001Service;
	private static final Logger LOG = LoggerFactory.getLogger(SD00001Controller.class);
	//根據項目編碼,獲取項目描述
	@RequestMapping("/Z_PLM_SAP_CRM_MASTER")
	@ResponseBody
	public Map<String, Object> Z_PLM_SAP_CRM_MASTER(@RequestParam("projectCodeList[]") List<String> projectCodeList ,String sapCode){
		return sd00001Service.getZ_PLM_SAP_MATLIST(projectCodeList,sapCode);//注意springmvc傳入list類型數據,需要增加@RequestParam
	}
	
	//校驗物料主數據是否有拓展
	@RequestMapping("/ZBPM_SD_CHECK_SALES_VIEW")
	@ResponseBody
    public Map<String, Object> ZBPM_SD_CHECK_SALES_VIEW(String MATNR, String VKORG,String VTWEG, String sapCode) {
		return sd00001Service.getZBPM_SD_CHECK_SALES_VIEW(MATNR, VKORG, VTWEG, sapCode);
	}
	
	//銷售價格寫入SAP系統
	@RequestMapping("/ZBPM_SD_CREATE_SALES_PRICE")
	@ResponseBody
    public Map<String, Object> ZBPM_SD_CREATE_SALES_PRICE(String CT_PRICE,String sapCode) {
		JSONArray rows = new JSONArray(CT_PRICE);
		return sd00001Service.getZBPM_SD_CREATE_SALES_PRICE(rows,sapCode);
	}	
	
    //接口無table名形式的SAP接口
    @RequestMapping("/Z_BPM_SD_GHOST_DN")
	@ResponseBody
    public Map<String, Object> Z_BPM_SD_GHOST_DN(String ID_VBELN, String ID_POSNR,String ID_WERKS, String ID_MATNR,String ID_CHARG,String ID_LGORT,String sapCode) {
		return sd00001Service.getZ_BPM_SD_GHOST_DN(ID_VBELN, ID_POSNR, ID_WERKS, ID_MATNR, ID_CHARG, ID_LGORT, sapCode);
	}

}

3. 實現Service層

package com.gzsolartech.portal.service.SD;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.gzsolartech.bpmportal.util.RfcManager;
import com.gzsolartech.smartforms.entity.DatApplication;
import com.gzsolartech.smartforms.service.BaseDataService;
import com.gzsolartech.smartforms.service.DatApplicationService;
import com.gzsolartech.smartforms.service.DatDocumentService;
import com.gzsolartech.smartforms.service.DetFormDefineService;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFieldIterator;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoTable;
@Service("SD00001Service")
public class SD00001Service extends BaseDataService{
	
	private static final Logger LOG = LoggerFactory.getLogger(SD00001Service.class);
	@Autowired
	private DatDocumentService datDocumentService;
	@Autowired
	private DatApplicationService datApplicationService;
	public Map<String, Object> getZ_PLM_SAP_MATLIST(List<String> projectCodeList,String sapCode) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			JCoFunction function = null;
			JCoDestination destination = null;
			RfcManager rfcManager = RfcManager.getInstance(getSAPConfig(sapCode));//獲取SAP客戶端
			destination = rfcManager.getDestination();
			function = rfcManager.getFunction(destination, "Z_PLM_SAP_CRM_MASTER");//調用SAP接口
			JCoParameterList tableParameterList = function.getTableParameterList();//獲取表格參數
			JCoTable inputTable = tableParameterList.getTable("T_INPUT");  //獲取輸入表T_INPUT的數據參數
			for(int i=0;i<projectCodeList.size();i++){
				//往輸入表中,給指定字段參數進行賦值
				inputTable.appendRow();
				inputTable.setRow(i);
				inputTable.setValue("PROJT", projectCodeList.get(i));
			}
			function.execute(destination);
			JCoTable outputTable = tableParameterList.getTable("T_OUTPUT");//獲取輸出表T_OUTPUT的數據
			for(int i=0;i<outputTable.getNumRows();i++){
				outputTable.setRow(i);
				map.put(outputTable.getString("PROJT"), outputTable.getString("PDESC"));//獲取輸出結果中的兩個字段,分別爲PROJT和PDESC
			}
		} catch (Exception e) {
			map.put("msg", "調用解析SAP接口Z_PLM_SAP_CRM_MASTER失敗"+e.getMessage());
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 校驗物料主數據是否有拓展
	 */
	public Map<String, Object> getZBPM_SD_CHECK_SALES_VIEW(String MATNR, String VKORG,String VTWEG, String sapCode) {
		Map<String, Object> result = new HashMap<String, Object>();
		// 返回表格參數
		int total = 0;
		List<Map<String,Object>> inveArray = new ArrayList<Map<String,Object>>();
		try {
			// 1. 初始化
			JCoFunction function = null;
			JCoDestination destination = null;
			JCoFieldIterator iterator = null;
			RfcManager rfcManager;
			rfcManager = RfcManager.getInstance(getSAPConfig(sapCode));
			destination = rfcManager.getDestination();
			function = rfcManager.getFunction(destination, "ZBPM_SD_CHECK_SALES_VIEW");
			// 2. 設置輸入參數
			JCoParameterList importParameterList = function.getTableParameterList();
			JCoTable inputTable = importParameterList.getTable("CT_MAT");  //獲取輸入表的數據參數
			inputTable.appendRow();
			inputTable.setRow(1);
			inputTable.setValue("MATNR", MATNR);
			inputTable.setValue("VKORG", VKORG);
			inputTable.setValue("VTWEG", VTWEG);
			// 3. 調用
			function.execute(destination);
			// 4. 獲取返回參數
			JCoTable outputTable = importParameterList.getTable("CT_MAT");//獲取輸出表的數據
			String MSGTX = (String) outputTable.getValue("MSGTX");
			String OKSTA = (String) outputTable.getValue("OKSTA");
			result.put("result", "Y".equals(OKSTA)? "success": "fail");
			result.put("msg", MSGTX);
		} catch (Exception e) {
			result.put("result", "fail");
			result.put("msg", "調用解析SAP接口ZBPM_SD_CHECK_SALES_VIEW"+e.getMessage());
			e.printStackTrace();
		} 
		return result;
	}
	
	/**
	 * 銷售價格寫入SAP
	 */
	 public Map<String, Object> getZBPM_SD_CREATE_SALES_PRICE(JSONArray rows,String sapCode) {
		Map<String, Object> result = new HashMap<String, Object>();
		// 返回表格參數
		int total = 0;
		List<Map<String,Object>> inveArray = new ArrayList<Map<String,Object>>();
		try {
			// 1. 初始化
			JCoFunction function = null;
			JCoDestination destination = null;
			JCoFieldIterator iterator = null;
			RfcManager rfcManager;
			rfcManager = RfcManager.getInstance(getSAPConfig(sapCode));
			destination = rfcManager.getDestination();
			function = rfcManager.getFunction(destination, "ZBPM_SD_CREATE_SALES_PRICE");
			// 2. 設置輸入參數
			JCoParameterList importParameterList = function.getTableParameterList();
			JCoTable inputTable = importParameterList.getTable("CT_PRICE");  //獲取輸入表的數據參數
			for(int i=0;i<rows.length();i++){
				inputTable.appendRow();
				inputTable.setRow(i);
				JSONObject row = rows.optJSONObject(i);
				inputTable.setValue("MATNR", row.optString("MATNR"));
				inputTable.setValue("VKORG", row.optString("VKORG"));
			}
			// 3. 調用
			function.execute(destination);
			// 4. 獲取返回參數
			JCoTable outputTable = importParameterList.getTable("CT_PRICE");//獲取輸出表的數據
			//獲取總行數
			total = outputTable.getNumRows();
			for (int i = 0; i < total; i++) {
				outputTable.setRow(i);
				//遍歷輸出參數表
				iterator = outputTable.getFieldIterator();
				Map<String,Object> item = new HashMap<>();
				while (iterator.hasNextField()) {
					JCoField field = iterator.nextField();
					item.put(field.getName(), field.getValue().toString());
				}
				inveArray.add(item);
			}
			result.put("result", true);
			result.put("data", inveArray);
			
		} catch (Exception e) {
			result.put("result", false);
			result.put("msg", "調用解析SAP接口ZBPM_SD_CREATE_SALES_PRICE"+e.getMessage());
			LOG.error("用解析SAP接口ZBPM_SD_CREATE_SALES_PRICE", e);
		} 
		return result;
	}
	
	public Map<String, Object> getZ_BPM_SD_GHOST_DN(String ID_VBELN, String ID_POSNR, String ID_WERKS,
			String ID_MATNR, String ID_CHARG, String ID_LGORT, String sapCode) {
		Map<String, Object> result = new HashMap<String, Object>();
		// 返回表格參數
		int total = 0;
		List<Map<String,Object>> inveArray = new ArrayList<Map<String,Object>>();
		try {
			// 1. 初始化
			JCoFunction function = null;
			JCoDestination destination = null;
			JCoFieldIterator iterator = null;
			RfcManager rfcManager;
			rfcManager = RfcManager.getInstance(getSAPConfig(sapCode));
			destination = rfcManager.getDestination();
			function = rfcManager.getFunction(destination, "Z_BPM_SD_GHOST_DN");
			JCoParameterList importParameterList = function.getImportParameterList();
			importParameterList.setValue("ID_VBELN",ID_VBELN);
			importParameterList.setValue("ID_POSNR",ID_POSNR);
			importParameterList.setValue("ID_WERKS",ID_WERKS);
			importParameterList.setValue("ID_MATNR",ID_MATNR);
			importParameterList.setValue("ID_CHARG",ID_CHARG);
			importParameterList.setValue("ID_LGORT",ID_LGORT);
			function.execute(destination);
			JCoParameterList output = function.getExportParameterList();
			String ED_MESSAGE = output.getString("ED_MESSAGE");
			String ED_ISOK = output.getString("ED_ISOK");
			result.put("ED_MESSAGE", ED_MESSAGE);
			result.put("ED_ISOK", ED_ISOK);
		} catch (Exception e) {
			result.put("flag", "fail");
			result.put("msg", "調用SAP接口Z_BPM_SD_GHOST_DN"+e.getMessage());
			e.printStackTrace();
		} 
		return result;
	}
}

4. 公用配置方法類

RfcManager

import com.sap.conn.jco.*;
import com.sap.conn.jco.ext.DestinationDataProvider;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
/**
 * 連接SAP
 */
public class RfcManager {

	private static final String ABAP_AS = "ABAP_AS_WITHOUT_POOL";
	private JCoDestination destination;
	private RfcManager(JSONObject SAPConfig) throws Exception {
		connect(SAPConfig);
	}

	public static RfcManager getInstance(JSONObject SAPConfig)
			throws Exception {
		RfcManager common = new RfcManager(SAPConfig);
		return common;
	}

	public void connect(JSONObject SAPConfig) throws Exception {
		String host = SAPConfig.get("ashost").toString();
		String clientName = SAPConfig.get("client").toString();
		String language = SAPConfig.get("langu").toString();
		String userId = SAPConfig.get("user").toString();
		String password = SAPConfig.get("passwd").toString();
		String system = SAPConfig.get("sysnr").toString();
		String JCO_PEAK_LIMIT = SAPConfig.get("Description").toString();
		Properties connectProperties = new Properties();
		connectProperties.clear(); 
		connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, host);
		connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, system);
		connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, clientName);
		connectProperties.setProperty(DestinationDataProvider.JCO_USER, userId);
		connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, password);
		connectProperties.setProperty(DestinationDataProvider.JCO_LANG, language);
		connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, JCO_PEAK_LIMIT);
		connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "30");
		try {
			createDataFile(ABAP_AS, "jcoDestination", connectProperties);
			destination = JCoDestinationManager.getDestination(ABAP_AS);
		} catch (JCoException ex) {
			throw new Exception("SAP連接失敗" + ex.getMessage());
		}
	}

	public JCoDestination getDestination(){
		try {
			destination = JCoDestinationManager.getDestination(ABAP_AS);
		} catch (JCoException e) {
			e.printStackTrace();
		}
		return destination;
	}

	public static void createDataFile(String name, String suffix, Properties properties)
			throws Exception {
		File cfg = new File(name + "." + suffix);
		try {
			FileOutputStream fos = new FileOutputStream(cfg, false);
			properties.store(fos, "ABAP_AS_WITHOUT_POOL");
			fos.close();
		} catch (Exception e) {
			throw new Exception("不能創建SAP連接需要的Destination文件" + cfg.getName());
		}
	}

	public JCoFunction getFunction(JCoDestination destination, String functionName) {
		JCoFunction function = null;
		 try {
			function = destination.getRepository().getFunctionTemplate(functionName).getFunction();
		} catch (JCoException e) {
			e.printStackTrace();
		}  
		return function;
	}

}

getSAPConfig

    //SAP連接配置,從前端配置表單SystemMG中獲取參數,表單名SAPConfig
	private JSONObject getSAPConfig(String SearchKey){
		DatApplication dat = datApplicationService.getDatApplicationByName("SystemMG");
		Map<String, Object> config = datDocumentService.getDocumentByField(dat.getAppId(), "SAPConfig", "SearchKey",SearchKey);
		Set keys = config.keySet();
		Iterator<String> iterator = keys.iterator();
		JSONObject SAPConfig = new JSONObject();
		while(iterator.hasNext()){
			String key = iterator.next();
			SAPConfig.put(key, config.get(key).toString());
		}
		return SAPConfig;
	}

6. SAP接口文檔

Z_PLM_SAP_CRM_MASTER接口文檔
在這裏插入圖片描述
ZBPM_SD_CHECK_SALES_VIEW接口文檔
在這裏插入圖片描述
ZBPM_SD_CREATE_SALES_PRICE接口文檔
在這裏插入圖片描述

7. 參考文章

訪問SAP統一RFC連接接口(RESTFUL風格)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章