SpringBoot项目使用JCO实现调用SAP接口实例
一、JCO接口介绍
JCO采用的是中间式接口,即外部系统将SAP系统所需的信息生成中间数据表,SAP系统直接读取中间文件或将中间表中的信息写入数据库中,中间式接口是比较常用的一种方式,这种方式外部系统和SAP系统相对独立,接口不涉及双方内部的结构,而且接口的责任也很明确,数据的安全性也得到了保证。但这种方式存在的问题就是两个系统的数据同步性稍差一些,但只要合理地规定读写中间文件或数据表的时间,数据的同步性是不会影响使用的。
二、JCO接口开发流程介绍
- 配置A系统和SAP系统的连接,建立两个系统的连接
- A系统获取需要调用SAP系统的方法,如ZBAPI_HAHA
- A系统传参数给方法
- 连接对象执行这个方法
- 获得返回的结果
- 释放连接
三、基于SpringBoot技术实际项目开发
1、配置A系统和SAP系统的连接,建立两个系统的连接,其中连接有两种连接
1)第一种连接配置
1.根据操作系统将sapjco3.dll文件放入C:\Windows\System32目录;
2.在项目中引入sapjco3.jar包;
3.创建DisplaySalesActivity.java类,配置生成连接
[code]public class DisplaySalesActivity { static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL"; static String DESTINATION_NAME2 = "ABAP_AS_WITH_POOL"; //配置连接 static { Properties connectProperties = new Properties(); connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "127.0.0.1");//IP connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00");//系统编号 connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "001");//客户端编号 connectProperties.setProperty(DestinationDataProvider.JCO_USER, "username");//用户名 connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password");//密码 connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "zh");//语言 createDestinationDataFile(DESTINATION_NAME1, connectProperties); connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "30");//最大空闲连接数 connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "150");//最大活动连接数 createDestinationDataFile(DESTINATION_NAME2, connectProperties); } /* *创建配置连接文件 / static void createDestinationDataFile(String destinationName, Properties connectProperties) { File destCfg = new File(destinationName + ".jcoDestination"); try { FileOutputStream fos = new FileOutputStream(destCfg, false); connectProperties.store(fos, "For tests only !"); fos.close(); } catch (Exception e) { throw new RuntimeException("Unable to create the destination files", e); } } /* *获取连接 / public static JCoDestination getSAPDestination() throws JCoException { JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME2); return destination; } public static void main(String[] args) throws JCoException { getSAPDestination(); }
配置好后运行main方法,生成2个连接配置文件(DESTINATION_NAME1 与DESTINATION_NAME2 )和2个日志文件,如果
在Tomcat中运行,配置好生成地址可以直接在应用中调连接方法。
(2)第二种连接配置(建议使用这种连接)
1.配置环境:
下载sapjco3.dll、librfc32.dll、sapjcorfc.dll放至C:\Windows\System32目录,缺一不可;
下载sapjco3.jar置放工程中,jar包可通过依赖导入或者直接下载。
这里分享一下sapjco3相关文件百度网盘,暂只供本机我自己的电脑(windows7系统,64bit)可用,如无法使用请重新去下载使用。
链接:https://pan.baidu.com/s/11kzlleiHqrkEuAu29ULEoA
提取码:lz0z
(包含sapjco3.dll、librfc32.dll、sapjcorfc.dll、sapjco3.jar)
这里温馨提醒一下,上面4个文件都是必须要配置成功的,不然会无法进行连接,出现一些连接问题。
如我遇到的几个问题:
[code]JCO.nativeInit(): Could not initialize dynamic link library librfc. Found version "640.0.144" but required at least version "640.0.377".] with root cause
2.配置访问属性文件
SAPConnectionPool.properties
jco.client.lang=zh #语言
jco.destination.peak_limit=150 #最大活动连接数
jco.client.client=001 #客户端编号
jco.client.passwd=password #密码
jco.client.user=username #用户名
jco.client.sysnr=00 #系统编号
jco.destination.pool_capacity=30 #最大空闲连接数
jco.client.ashost=127.0.0.1 #IP
2、封装获取链接池链接Java类,以便接口使用时调用
[code] import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sap.mw.jco.IFunctionTemplate; import com.sap.mw.jco.JCO; import com.sap.mw.jco.JCO.Client; import com.sap.mw.jco.JCO.Function; import com.sap.mw.jco.JCO.Repository; import com.sap.mw.jco.JCO.Table; import ep.dhcsoft.java.OrderedProperties; public class SAPConn { private static final String POOL_NAME = "Pool"; //这里value为空的字段,暂时没看到哪里用到过 private static String clientNum = ""; //客户端编号 private static String userName = ""; //用户名 private static String password = ""; //密码 private static String hostname = ""; // private static String systemnumber = ""; //系统编号 private static String Language = ""; private static com.sap.mw.jco.JCO.Pool pool = null; private static int maxconn = 120; //最大连接数 private static String sources = ""; private static Log log = LogFactory.getLog(SAPConn.class); public Client getSAPPoolConnection() { JCO.Client mConn = null; try { log.info("-------------SAP Client Connects Start ----------------"); Properties props = new Properties(); InputStream in = SAPConn.class.getResourceAsStream("/SAPConnectionPool.properties"); props.load(in); pool = JCO.getClientPoolManager().getPool(POOL_NAME);//这里有异常,这里pool为null if(pool == null){ JCO.addClientPool(POOL_NAME, maxconn,props);//这里重新去获取 } mConn = JCO.getClient(POOL_NAME); log.info("get connection success"); } catch(Exception exception) { log.info((new StringBuilder()).append("get connection error:").append(exception).toString()); } return mConn; } public void releaseC(JCO.Client client){ //释放连接 if(client != null) { JCO.releaseClient(client); } } //获取 sap bapi 方法 public Function excuteBapi(String s,Client mConn) { Function function = null; try { JCO.Repository mRepository; mRepository = new JCO.Repository("ARAsoft", mConn); IFunctionTemplate ft = mRepository.getFunctionTemplate(s); function = ft.getFunction(); } catch (Exception localException) { localException.printStackTrace(); log.error(localException); } return function; } /** * 获取结果集 封装在map 中 ,键值为rslist * @param solist * @return */ public static Map getSuccessMap(Table solist) { Map<String, Object> retMap = new HashMap<String, Object>(); List rslist = new ArrayList(); if (solist.getNumRows() > 0) { do { Map<String,String> tempmap = new HashMap(); for (JCO.FieldIterator fI = solist.fields(); fI .hasMoreElements();) { JCO.Field tabField = fI.nextField(); tempmap.put(tabField.getName(), tabField.getString()); } rslist.add(tempmap); } while (solist.nextRow() == true); } retMap.put("result", rslist); retMap.put("success", "true"); return retMap; } }
3、建立的连接demo
1、controller请求
[code] /** * 通过接口获得数据 * */ @RequestMapping(value = "/querySettlementCurrency") @ResponseBody public Map<String, Object> querySettlementCurrency(AccountInfo record,QueryParams qps,HttpSession session, HttpServletRequest request, HttpServletResponse response) { Map<String, Object> result = new HashMap<String, Object>(); SettlementCurrency settlementCurrency = new SettlementCurrency(); result=settlementCurrency.getSettlementCurrency(); System.out.println("result:"+result); return result; }
2、SettlementCurrency连接demo
[code] import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import com.sap.conn.jco.JCoStructure; import com.sap.mw.jco.IFunctionTemplate; import com.sap.mw.jco.JCO; import com.sap.mw.jco.JCO.ParameterList; import com.sap.mw.jco.JCO.Structure; import com.sap.mw.jco.JCO.Table; import ep.dhcsoft.java.OrderedProperties; /* * 弹窗出现数组接口 * * */ public class SettlementCurrency { static final String POOL_NAME = "Pool"; public Map<String, Object> getSettlementCurrency() { JCO.Client mConn = null; Map<String, Object> resultMap = new HashMap<>(); SAPConn sapConn = new SAPConn(); try { mConn = sapConn.getSAPPoolConnection();//这里有异常,无法获得连接 JCO.Function function = sapConn.excuteBapi("AAA",mConn); //执行接口 mConn.execute(function); //接口返回结果 JCO.Table returnStructure = function.getTableParameterList().getTable("Return"); resultMap= SAPConn.getSuccessMap(returnStructure); JCO.releaseClient(mConn);/*deprecated是表示这是个过时的方法,将来会被取消的,现在有主要是为了老代码的兼容;*/ }catch(Exception exception){ System.out.println(exception.getMessage()); } finally{ sapConn.releaseC(mConn); //释放连接 } return resultMap; //返回从SAP获取的结果。 } }
- JAVA使用JCO实现调用SAP接口方法
- JAVA使用JCO实现SAP接口调用环境配置说明
- ThreadLocal的实现原理,及使用实例,解决spring,hibernate非web项目下的懒加载 no session or session was closed(1)!
- 56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】
- 使用httpclient实现http接口调用实例
- Spring Boot中使用@Async实现异步调用
- Myeclipse下使用Maven搭建spring boot项目采用spring boot devtools实现热部署
- spring boot 使用@Async实现异步调用方法
- 使用httpclient实现http接口调用实例
- SpringBoot系列十一:SpringBoot整合Restful架构(使用 RestTemplate 模版实现 Rest 服务调用、Swagger 集成、动态修改日志级别)
- 使用jacoco+ant实现服务器上spring boot项目的代码覆盖率
- springboot项目使用jasypt实现自定义配置文件内容加密
- zTree的调用设使用(跨两个系统,两类技术实现的项目案例SpringMVC+Spring+MyBatis和Struts2+Spring+ibatis框架组合)
- SpringBoot项目,解决使用RestTemplate掉第三方接口报错406 Not Acceptable
- 使用Spring特性实现接口多实现类的动态调用
- Spring Boot项目利用Redis实现session管理实例
- 如何在Spring Boot中使用TDD写出高质量的接口(TDD实例)
- Spring Boot 使用@Async实现异步调用
- Spring Boot使用@Async实现异步调用:自定义线程池
- Spring Boot使用@Async实现异步调用