天天看点

SpringBoot JCO3 windows平台的实现。

背景:通过java实现与sap rfc接口的连接我们需要引入jco3 ,本篇主要介绍用springboot在windows平台的开发实现,下一篇将介绍jco3工程发布到云平台docker容器。

本篇配置:windows10+IDEA (均为64bit)

1. 首先将sapjco3.dll(64bit)放到c:\windows\system32 和c:\windows\sysWow64

2.创建maven工程 引入依赖,无需引入sapjco3.jar等其他jar包 。

<dependency>
    <groupId>org.hibersap</groupId>
    <artifactId>com.sap.conn.jco.sapjco3</artifactId>
    <version>3.0.14</version>
</dependency>      

3.本工程的sap连接配置放到yml文件中。我们写一个sap连接配置文件

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
 * 与SAP连接配置
 *
 * @author jay
 */
@Configuration
public class SAPConnConfig {
    private static Logger logger = LoggerFactory.getLogger(SAPConnConfig.class);
    private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";

    @Value("${jco.client.ashost}")
    private String ashost;//sap IP 地址

    @Value("${jco.client.sysnr}")
    private String sysnr;//实例 00

    @Value("${jco.client.client}")
    private String client;//客户端 202 800等

    @Value("${jco.client.user}")
    private String user;//用户名

    @Value("${jco.client.passwd}")
    private String passwd; //密码

    @Value("${jco.client.lang}")
    private String lang;//语言

    public String getAshost() {
        return ashost;
    }

    public void setAshost(String ashost) {
        this.ashost = ashost;
    }

    public String getSysnr() {
        return sysnr;
    }

    public void setSysnr(String sysnr) {
        this.sysnr = sysnr;
    }

    public String getClient() {
        return client;
    }

    public void setClient(String client) {
        this.client = client;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    public String getLang() {
        return lang;
    }

    public void setLang(String lang) {
        this.lang = lang;
    }
}
           

4 配置文件写好之后,我们接下来写的是jco3的连接方法

import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;

/**
 * 与SAP连接配置
 *
 * @author jay
 */
public final class SAPConnUtil {
    private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";

    private static Logger logger = LoggerFactory.getLogger(SAPConnUtil.class);

    static {
        SAPConnConfig sapConnConfig = SpringContextUtil.getBean(SAPConnConfig.class);

        Properties connectProperties = new Properties();
        //105系统 测试
        String sss = sapConnConfig.getAshost();
        connectProperties.setProperty("jco.client.ashost", sapConnConfig.getAshost());
        connectProperties.setProperty("jco.client.sysnr", sapConnConfig.getSysnr());
        connectProperties.setProperty("jco.client.client", sapConnConfig.getClient());
        connectProperties.setProperty("jco.client.user", sapConnConfig.getUser());
        connectProperties.setProperty("jco.client.passwd", sapConnConfig.getPasswd());
        connectProperties.setProperty("jco.client.lang", sapConnConfig.getLang());

        //JCo连接到SAP服务器有两种方法,分别是直连和通过连接池进行连接。其差别在于,打开直连连接后可以一直保持连接;连接池则是在需要时才建立连接,连接暂不需要时,将被释放回连接池,再分配给其他用户使用。在网络服务器应用程序里,一般采用连接池进行连接SAP服务器。
        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");  //最大连接数
        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");     //最大连接线程
        createDataFile(ABAP_AS_POOLED, "jcoDestination", connectProperties);
    }

    /**
     * 创建SAP接口属性文件。
     *
     * @param name       ABAP管道名称
     * @param suffix     属性文件后缀
     * @param properties 属性文件内容
     */
    private static void createDataFile(String name, String suffix, Properties properties) {
        File cfg = new File(name + "." + suffix);
        if (cfg.exists()) {
            cfg.deleteOnExit();
        }
        try {
            FileOutputStream fos = new FileOutputStream(cfg, false);
            properties.store(fos, "for tests only !");
            fos.close();
        } catch (Exception e) {
            logger.error("Create Data file fault, error msg: " + e.toString());
            throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
        }
    }

    /**
     * 获取SAP连接
     *
     * @return SAP连接对象
     */
    public static JCoDestination connect() {
        JCoDestination destination = null;
        try {
            destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
        } catch (JCoException e) {
            logger.error("Connect SAP fault, error msg: " + e.toString());
            throw new RuntimeException("Unable to create the destination file ", e);
        }
        return destination;
    }
}  
           

5.上面我们需要从spring上下文中获取SAPConnConfig中的配置信息,因此我们创建SpringContextUtil工具类

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Spring工具类,获取Spring上下文对象等
 */
@Component
public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringContextUtil.applicationContext == null){
            SpringContextUtil.applicationContext  = applicationContext;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }
}
           

6 ,最后我们写代码连接rfc接口即可。部分代码如下,其余代码请参考我的另一篇文章https://blog.csdn.net/lida1001/article/details/54314832

JCoDestination destination = SAPConnUtil.connect();//获取连接
        JCoFunction function  = destination.getRepository().getFunction(funcName);//获取rfc函数
        JCoParameterList input = function.getImportParameterList();//获取输入参数