JAVA调用Sap的RFC

SAP目前是世界上最大的也是使用最多的ERP系统,很多大型系统都将自己的业务数据放到了SAP系统来进行管理,那么当别的系统需要这些数据时,就需要从SAP中获取这些数据。SAP中有各种不同类型的接口,RFC,PI等等。下面记录的是java如何调用RFC的接口。网上可以找到很多类似的文章,代码也是以前的老手写的,也比较易懂,这里再记下来主要是为了以后找起来方便。

java调用RFC接口需要用到sapjco3.jar,windows下还需要将文件sapjco3.dll文件放到system32的目录下,linux下同样需要把sapjco3.so放入项目的执行目录下

需要的sapjco3.dll、sapjco3.so、sapjco3.jar 我放百度云链接:https://pan.baidu.com/s/1upV7J-JdkiKaH1SczFK6nA        提取码:t33y

其实只需要sapjco3.dll(windows)、sapjco3.so(linux)

有两种方式:

1.sapjco3.jar 放在项目路径下 打包注意一下 具体不详细介绍了。

2.Maven的方式引入:

<properties>
		<sapjco3.version>3.0.11</sapjco3.version>
</properties>

<dependency>
	    <groupId>com.github.easonjim</groupId>
		<artifactId>com.sap.conn.jco.sapjco3</artifactId>
		<version>${sapjco3.version}</version>
</dependency>

代码如下:

RfcManager.java:

package com.thescm.console.jco;

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

import java.util.Properties;

/**
 * RFC 配置中心
 *
 * @author SJ
 * @date 2021-1-4 16:32:01
 */
public final class RfcManager {
    private final static Logger logger = LoggerFactory.getLogger(RfcManager.class);
    private static final String ABAP_AS_POOLED = "ABAP_AS_POOL";
    private static JcoProvider provider;
    private static JCoDestination destination;

    static {
        Properties properties = loadProperties();
        // catch IllegalStateException if an instance is already registered
        try {
            provider = new JcoProvider();
            Environment.registerDestinationDataProvider(provider);
            provider.changePropertiesForABAP_AS(ABAP_AS_POOLED, properties);
        } catch (Exception e) {
            logger.error("RfcManager registerDestinationDataProvider error:"+e.getMessage(), e);
        }
    }

    public static Properties loadProperties() {
        Properties connectProperties = new Properties();
        // SAP服务器
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.xx.xx");
        // SAP端口
        connectProperties.setProperty(DestinationDataProvider.JCO_MSSERV, "");
        // SAP系统编号
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "xx");
        // SAP集团
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "xxx");
        // SAP用户名
        connectProperties.setProperty(DestinationDataProvider.JCO_USER, "xxxxx");
        // SAP密码
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxx");
        // SAP登录语言
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "zh");
        // 最大连接数
        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "xx");
        // 最大连接线程
        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "xx");
        // 连接路由
        connectProperties.setProperty(DestinationDataProvider.JCO_SAPROUTER, "/x/xxxxx");

        return connectProperties;
    }

    public static JCoDestination getDestination() throws JCoException {
        if (destination == null) {
            destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);
        }
        return destination;
    }

    public static void execute(JCoFunction function) {
        logger.info("SAP Function Name : " + function.getName());
        try {
            function.execute(getDestination());
        } catch (JCoException e) {
            logger.error("RfcManager execute error:", e);
        }
    }

    public static JCoFunction getFunction(String functionName) {
        JCoFunction function = null;
        try {
            function = getDestination().getRepository().getFunctionTemplate(functionName).getFunction();
        } catch (JCoException e) {
            logger.error("RfcManager getFunction JCoException error:", e);
        } catch (NullPointerException e) {
            logger.error("RfcManager getFunction NullPointerException error:", e);
        }
        return function;
    }
}
RfcSessionReference.java
package com.thescm.console.jco;

import com.sap.conn.jco.ext.JCoSessionReference;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * RFC SESSION 管理中心
 *
 * @author SJ
 * @date 2021-1-4 16:32:21
 */
public class RfcSessionReference implements JCoSessionReference {
    static AtomicInteger atomicInt = new AtomicInteger(0);
    private String id = "session-" + String.valueOf(atomicInt.addAndGet(1));

    @Override
    public void contextFinished() {
    }

    @Override
    public void contextStarted() {
    }

    @Override
    public String getID() {
        return id;
    }

}
JcoProvider.java
package com.thescm.console.jco;

import com.sap.conn.jco.ext.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Properties;

/**
 * JCO 提供方
 *
 * @author SJ
 * @date 2021-1-4 16:33:02
 */
public class JcoProvider implements DestinationDataProvider, SessionReferenceProvider {

    private final static Logger logger = LoggerFactory.getLogger(JcoProvider.class);
    private HashMap<String, Properties> secureDBStorage = new HashMap<>();
    private DestinationDataEventListener eL;

    @Override
    public Properties getDestinationProperties(String destinationName) {
        try {
            //read the destination from DB
            Properties p = secureDBStorage.get(destinationName);
            if (p != null) {
                //check if all is correct, for example
                if (p.isEmpty()) {
                    logger.info("destination configuration is incorrect!");
                }
                return p;
            }
            logger.info("properties is null ...");
            return null;
        } catch (RuntimeException re) {
            logger.error("internal error!");
            return null;
        }
    }

    @Override
    public void setDestinationDataEventListener(
            DestinationDataEventListener eventListener) {
        this.eL = eventListener;
        logger.info("eventListener assigned ! ");
    }

    @Override
    public boolean supportsEvents() {
        return true;
    }

    /**
     * implementation that saves the properties in a very secure way
     */
    public void changePropertiesForABAP_AS(String destName, Properties properties) {
        synchronized (secureDBStorage) {
            if (properties == null) {
                if (secureDBStorage.remove(destName) != null) {
                    eL.deleted(destName);
                }
            } else {
                secureDBStorage.put(destName, properties);
                // create or updated
                eL.updated(destName);
            }
        }
    }

    @Override
    public JCoSessionReference getCurrentSessionReference(String scopeType) {

        RfcSessionReference sesRef = JcoMutiThread.localSessionReference.get();
        if (sesRef != null) {
            return sesRef;
        }
        throw new RuntimeException("Unknown thread:" + Thread.currentThread().getId());
    }

    @Override
    public boolean isSessionAlive(String sessionId) {
        return false;
    }

    @Override
    public void jcoServerSessionContinued(String sessionID)
            throws SessionException {
    }

    @Override
    public void jcoServerSessionFinished(String sessionID) {

    }

    @Override
    public void jcoServerSessionPassivated(String sessionID)
            throws SessionException {
    }

    @Override
    public JCoSessionReference jcoServerSessionStarted() throws SessionException {
        return null;
    }
}
JcoMutiThread.java
package com.thescm.console.jco;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Hashtable;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * JCO线程操作
 *
 * @author SJ
 * @date 2021-1-4 15:34:35
 */
public class JcoMutiThread extends Thread {

    private final static Logger logger = LoggerFactory.getLogger(JcoMutiThread.class);
    public static Hashtable<IMultiStepJob, RfcSessionReference> sessions = new Hashtable<>();
    public static ThreadLocal<RfcSessionReference> localSessionReference = new ThreadLocal<>();
    private BlockingQueue<IMultiStepJob> queue;
    private CountDownLatch doneSignal;
    private boolean isSapBusy = false;


    public JcoMutiThread(CountDownLatch doneSignal, BlockingQueue<IMultiStepJob> queue) {
        this.doneSignal = doneSignal;
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (; ; ) {
                IMultiStepJob job = queue.poll(10, TimeUnit.SECONDS);

                // stop if nothing to do
                if (job == null) {
                    break;
                }
                if (isSapBusy) {
                    Thread.sleep(5000);
                }
                RfcSessionReference sesRef = sessions.get(job);
                if (sesRef == null) {
                    sesRef = new RfcSessionReference();
                    sessions.put(job, sesRef);
                }
                localSessionReference.set(sesRef);
                try {
                    isSapBusy = job.runNextStep();
                } catch (Throwable th) {
                    logger.error("JcoMutiThread runNextStep", th);
                }

                if (isSapBusy) {
                    queue.add(job);
                } else {
                    sessions.remove(job);
                    job.cleanUp();
                }
                localSessionReference.set(null);
            }
        } catch (InterruptedException e) {
            logger.error("JcoMutiThread run", e);
        } finally {
            doneSignal.countDown();
        }
    }
}
IMultiStepJob.java
package com.thescm.console.jco;

/**
 * 多步骤任务
 *
 * @author SJ
 * @date 2021-1-4 10:10:16
 */
public interface IMultiStepJob {
    boolean runNextStep();

    String getName();

    void cleanUp();
}
 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值