访问SAP统一RFC连接接口(RESTFUL风格)

17 篇文章 1 订阅
13 篇文章 0 订阅

项目基于Spring 4.3.7 + Hibernate 4.3.11

1. 定义必要的POJO类

用于查询数据库并将数据封装到类中
DatApplication

package com.jake.rfcrabbitmvc.pojo;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Data
@Entity
@Table(name = "DAT_APPLICATION")
public class DatApplication {

    @Id
    @Column(name = "APP_ID", unique = true, nullable = false, length = 100)
    private String appId;

    @Column(name = "APP_NAME", nullable = false, length = 100)
    private String appName;

}

DatDocument

package com.jake.rfcrabbitmvc.pojo;

import lombok.Data;
import org.hibernate.annotations.Type;
import org.w3c.dom.Document;

import javax.persistence.*;

@Data
@Entity
@Table(name = "DAT_DOCUMENT")
public class DatDocument {

    @Id
    @Column(name = "DOCUMENT_ID", unique = true, nullable = false, length = 100)
    private String datDocumentId;

    @Type(type = "com.jake.tooljar.hiextype.OracleXmlType")
    @Column(name = "DOCUMENT_DATA", columnDefinition = "XMLTYPE")
    private Document document;

}

2. 定义必要的管理、配置类

RfcManager

package com.jake.rfcrabbitmvc.manager;

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;
	}

}

SAPConstant

package com.jake.rfcrabbitmvc.constant;

public class SAPConstant {

    public static final String DEFAULT_SEARCH_KEY = "QAS_800";

    public static final String DEFAULT_CLIENT = "800";

}

3. 实现Dao层

本项目的Dao层用于从Oracle中查出必要的SAP配置参数,使用了泛型。

接口BaseDao,定义Hibernate的HQL和SQL的JDBC查询方法

package com.jake.rfcrabbitmvc.dao;

import java.util.List;

public interface BaseDao<T> {

    List<T> queryHQL(String hql, Object... params);

    List<T> executeJDBCSqlQuery(String sql, Class clazz, List<String> params);

}

实现类BaseDaoImpl

package com.jake.rfcrabbitmvc.dao.impl;

import com.jake.rfcrabbitmvc.dao.BaseDao;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@SuppressWarnings("unchecked")
@Repository
@Transactional
public class BaseDaoImpl<T> implements BaseDao<T> {

    @Autowired
    private SessionFactory sessionFactory;

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public List<T> queryHQL(String hql, Object... params) {
        Query query = getSession().createQuery(hql);
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                query.setParameter(i, params[i]);
            }
        }
        return query.list();
    }


    @Override
    public List<T> executeJDBCSqlQuery(String sql, Class clazz, List<String> params) {
        SQLQuery sqlQuery = getSession().createSQLQuery(sql);
        for(int i = 0; i < params.size(); i++){
            sqlQuery.setParameter(i, params.get(i));
        }
        return sqlQuery.addEntity(clazz).list();
    }

}

4. 实现Service层

BpmToSapService接口定义方法

package com.jake.rfcrabbitmvc.service;

import com.jake.rfcrabbitmvc.manager.RfcManager;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import org.json.JSONObject;

import java.util.List;
import java.util.Map;

public interface BpmToSapService {

    /**
     * @param map 前端请求体中携带的Json数据
     * @return 返回result给响应体
     */
    Map<String, Object> getSapJson(Map<String, Object> map);

    /**
     * 根据请求体中的client或searchKey获取连接SAP的RFCManager
     * @param map 请求体携带的Json数据
     * @return RfcManager
     * @throws Exception
     */
    RfcManager getRfcManager(Map<String, Object> map) throws Exception;

    /**
     * 根据searchKey获取对应的sap配置
     * @param searchKey 值为QAS_800, QAS_900
     * @return SAP配置信息
     */
    JSONObject getSAPConfigBySearchKey(String searchKey);

    /**
     * 根据client获取对应的sap配置
     * @param client 值为800, 900, 200
     * @return SAP配置信息
     */
    JSONObject getSAPConfigByClient(String client);

    /**
     * @param name "client" or "SearchKey"
     * @param value 对应的值
     * @return
     */
    JSONObject getSAPConfig(String name, String value);

    /**
     * 设置SAP普通入参
     * @param inputParamMap SAP普通入参Map,从前端请求体中获取。
     * @param importParameterList SAP普通入参集合,由function获取。
     */
    void setNormalInput(Map<String, String> inputParamMap, JCoParameterList importParameterList);

    /**
     * 设置SAP table入参
     * @param inputTableMap SAP普通入参Map,从前端请求体中获取。
     * @param tableParameterList SAP table类型入参集合,由function获取。
     */
    void setTableInput(Map<String, Map<String, String>> inputTableMap, JCoParameterList tableParameterList);

    /**
     * @param result 返还给响应体的JSON数据
     * @param outputParamNameList 输出参数名集合,从前端请求体中获取。
     * @param function JCoFunction类型,已经在设置完入参后执行过
     */
    void setNormalOutput(Map<String, Object> result, List<String> outputParamNameList, JCoFunction function);

    /**
     * @param result 返还给响应体的JSON数据
     * @param outputTableMap 输出table Map,从前端请求体中获取。
     * @param function JCoFunction类型,已经在设置完入参后执行过
     */
    void setTableOutput(Map<String, Object> result, Map<String, List<String>> outputTableMap, JCoFunction function);

}

BpmToSapServiceImpl实现该接口方法

package com.jake.rfcrabbitmvc.service.impl;

import com.jake.rfcrabbitmvc.constant.SAPConstant;
import com.jake.rfcrabbitmvc.manager.RfcManager;
import com.jake.rfcrabbitmvc.pojo.DatApplication;
import com.jake.rfcrabbitmvc.service.BpmToSapService;
import com.jake.rfcrabbitmvc.service.DatApplicationService;
import com.jake.rfcrabbitmvc.service.DatDocumentService;
import com.sap.conn.jco.*;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 方法详细注释在BpmToSapService接口中
 */
@Service
@SuppressWarnings("unchecked")
public class BpmToSapServiceImpl implements BpmToSapService {

    @Autowired
    private DatApplicationService datApplicationService;

    @Autowired
    private DatDocumentService datDocumentService;

    @Override
    public Map<String, Object> getSapJson(Map<String, Object> requestMap) {
        Map<String, Object> responseMap = new HashMap<>();
        try {
            RfcManager rfcManager = getRfcManager(requestMap);
            JCoDestination destination = rfcManager.getDestination();
            String functionName = (String) requestMap.get("functionName");
            JCoFunction function = rfcManager.getFunction(destination, functionName);
            Map<String, String> inputParamMap = (Map<String, String>) requestMap.get("inputParamMap");
            Map<String, Map<String, String>> inputTableMap = (Map<String, Map<String, String>>) requestMap.get("inputTableMap");
            Map<String, List<String>> outputTableMap = (Map<String, List<String>>) requestMap.get("outputTableMap");
            List<String> outputParamNameList = (List<String>) requestMap.get("outputParamNameList");
            String inputType = null;
            String outputType = null;
            // 多一段关于输入类型的判断和赋值,使得不同输入输出类型的组合下的逻辑处理更清晰,增强代码可读性。
            // normal表示SAP入参/出参为普通类型,table表示SAP入参/出参为表类型
            if (inputParamMap != null && inputTableMap == null) {
                inputType = "normal";
            } else if (inputParamMap == null && inputTableMap != null) {
                inputType = "table";
            }
            if (outputParamNameList != null && outputTableMap == null) {
                outputType = "normal";
            } else if (outputParamNameList == null && outputTableMap != null) {
                outputType = "table";
            }
            JCoParameterList importParameterList = function.getImportParameterList();
            JCoParameterList tableParameterList = function.getTableParameterList();
            if (StringUtils.equals(inputType, "normal") &&
                    StringUtils.equals(outputType, "normal")) {
                setNormalInput(inputParamMap, importParameterList);
                function.execute(destination);
                setNormalOutput(responseMap, outputParamNameList, function);
            } else if (StringUtils.equals(inputType, "normal") &&
                    StringUtils.equals(outputType, "table")) {
                setNormalInput(inputParamMap, importParameterList);
                function.execute(destination);
                setTableOutput(responseMap, outputTableMap, function);
            } else if (StringUtils.equals(inputType, "table") &&
                    StringUtils.equals(outputType, "normal")) {
                setTableInput(inputTableMap, tableParameterList);
                function.execute(destination);
                setNormalOutput(responseMap, outputParamNameList, function);
            } else if (StringUtils.equals(inputType, "table") &&
                    StringUtils.equals(outputType, "table")) {
                setTableInput(inputTableMap, tableParameterList);
                function.execute(destination);
                setTableOutput(responseMap, outputTableMap, function);
            } else {
                responseMap.put("message", "输入输出类型组合不正确");
                return responseMap;
            }
            responseMap.put("message", "success");
        } catch (Exception e) {
            e.printStackTrace();
            responseMap.put("error", e.getMessage());
            responseMap.put("message", "fail");
        }
        return responseMap;
    }

    @Override
    public RfcManager getRfcManager(Map<String, Object> map) throws Exception {
        RfcManager rfcManager = null;
        if (map.containsKey("searchKey")) {
            String searchKey = (String) map.get("searchKey");
            if (StringUtils.isEmpty(searchKey)) {
                searchKey = SAPConstant.DEFAULT_SEARCH_KEY;
            }
            rfcManager = RfcManager.getInstance(getSAPConfigBySearchKey(searchKey));
        } else if (map.containsKey("client")) {
            String client = (String) map.get("client");
            if (StringUtils.isEmpty(client)) {
                client = SAPConstant.DEFAULT_CLIENT;
            }
            rfcManager = RfcManager.getInstance(getSAPConfigByClient(client));
        }
        return rfcManager;
    }

    public JSONObject getSAPConfigBySearchKey(String searchKey) {
        return getSAPConfig("SearchKey", searchKey);
    }

    public JSONObject getSAPConfigByClient(String client) {
        return getSAPConfig("client", client);
    }

    public JSONObject getSAPConfig(String name, String value) {
        DatApplication dat = datApplicationService.getDatApplicationByName("SystemMG");
        Map<String, Object> config = datDocumentService.getDocumentByField(dat.getAppId(), "SAPConfig", name, value);
        Set<String> 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;
    }

    public void setNormalInput(Map<String, String> inputParamMap, JCoParameterList importParameterList) {
        Set<String> inputParamNameSet = inputParamMap.keySet();
        for (String inputParamName : inputParamNameSet) {
            if (StringUtils.isNotEmpty(inputParamName)) {
                importParameterList.setValue(inputParamName, inputParamMap.get(inputParamName));
            }
        }
    }

    public void setTableInput(Map<String, Map<String, String>> inputTableMap, JCoParameterList tableParameterList) {
        int index = 0;
        Set<String> tableNameSet = inputTableMap.keySet();
        for (String tableName : tableNameSet) {
            JCoTable table = tableParameterList.getTable(tableName);
            table.appendRow();
            table.setRow(index);
            index++;
            Map<String, String> paramMap = inputTableMap.get(tableName);
            Set<String> paramNameSet = paramMap.keySet();
            for (String paramName : paramNameSet) {
                table.setValue(paramName, paramMap.get(paramName));
            }
        }
    }

    public void setNormalOutput(Map<String, Object> result, List<String> outputParamNameList, JCoFunction function) {
        JCoParameterList exportParameterList = function.getExportParameterList();
        Map<String, String> responseOutputParamMap = new HashMap<>();
        if (outputParamNameList.isEmpty()) {
            for (JCoField jCoField : exportParameterList) {
                responseOutputParamMap.put(jCoField.getName(), jCoField.getValue().toString());
            }
        } else {
            for (String outputParamName : outputParamNameList) {
                responseOutputParamMap.put(outputParamName, exportParameterList.getString(outputParamName));
            }
        }
        result.put("responseOutputParamMap", responseOutputParamMap);
    }

    public void setTableOutput(Map<String, Object> result, Map<String, List<String>> outputTableMap, JCoFunction function) {
        JCoParameterList tableParameterList = function.getTableParameterList();
        Map<String, List<Map<String, String>>> responseOutputParamMap = new HashMap<>();
        List<Map<String, String>> responseOutputParamMapList = new ArrayList<>();
        if (outputTableMap != null) {
            for (String outputTableName : outputTableMap.keySet()) {
                JCoTable table = tableParameterList.getTable(outputTableName);
                List<String> outputParamNameList = outputTableMap.get(outputTableName);
                for (int i = 0; i < table.getNumRows(); i++) {
                    Map<String, String> outputParamMap = new HashMap<>();
                    table.setRow(i);
                    if (outputParamNameList.isEmpty()) {
                        for (JCoField jCoField : table) {
                            outputParamMap.put(jCoField.getName(), jCoField.getValue().toString());
                        }
                    } else {
                        for (String outputParamName : outputParamNameList) {
                            outputParamMap.put(outputParamName, table.getString(outputParamName));
                        }
                    }
                    responseOutputParamMapList.add(outputParamMap);
                }
                responseOutputParamMap.put(outputTableName, responseOutputParamMapList);
            }
        }
        result.put("responseOutputTableMap", responseOutputParamMap);
    }

}

5. 实现Controller层

控制层,用于向前端提供HTTP测试接口,返回响应Json数据。

package com.aac.rfcrabbitmvc.controller;

import com.aac.rfcrabbitmvc.service.BpmToSapService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * BPM从SAP获取数据的统一接口类
 * @author Jake Weng
 */
@RestController
@RequestMapping(value = "/sap")
public class BpmToSapController {

    @Autowired
    private BpmToSapService bpmToSapService;

    /**
     * HTTP接口定义处
     * Postman中选择POST请求,请求体选择raw -> application/json类型
     * 请求体中的Json数据写法请参照《SAP统一接口文档》
     *
     * @param requestMap 前端请求体中携带的Json数据
     * @return 返回result给响应体
     */
    @RequestMapping(value = "/json")
    public Map<String, Object> getSapJson(@RequestBody Map<String, Object> requestMap) {
        return bpmToSapService.getSapJson(requestMap);
    }

}

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值