访问SAP统一RFC连接接口(RESTFUL风格)详解编程语言

项目基于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); 
} 
} 

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/19593.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论