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