java调用sap的RFC接口

来源:互联网 发布:斯坦福英语软件下载 编辑:程序博客网 时间:2024/05/14 13:04

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

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


JOCTest:

package jco;import com.sap.conn.jco.JCoFunction;import com.sap.conn.jco.JCoParameterList;import com.sap.conn.jco.JCoTable;import java.util.ArrayList;import java.util.List;public class JCOTest {    public static void main(String[] args)    {        getUser();    }    public static List<User> getUser() {        JCoFunction function = RfcManager.getFunction("FUNCION_USER");        RfcManager.execute(function);        JCoParameterList outputParam = function.getTableParameterList();        JCoTable bt = outputParam.getTable("TABLEOUT");        List<User> list = new ArrayList<User>();        for (int i = 0; i < bt.getNumRows(); i++) {            bt.setRow(i);            User user = new User();            user.setUserName(bt.getString("USER_NAME"));            list.add(user);        }        return list;    }}
RfcManager:
package jco;import com.sap.conn.jco.*;import com.sap.conn.jco.ext.Environment;import java.io.IOException;import java.util.Properties;public final class RfcManager {    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 (IllegalStateException e) {            System.out.println(e.getMessage());        }    }    public static Properties loadProperties() {        Properties props=new Properties();        props.setProperty("jco.client.user","value");        props.setProperty("jco.client.passwd","value");        props.setProperty("jco.client.lang", "value");        props.setProperty("jco.client.client","value");        props.setProperty("jco.client.sysnr","value");        props.setProperty("jco.client.ashost","value");        props.setProperty("jco.destination.peak_limit","value");        props.setProperty("jco.destination.pool_capacity","value");        return props;    }    public static JCoDestination getDestination() throws JCoException {        if (destination == null) {            destination = JCoDestinationManager.getDestination(ABAP_AS_POOLED);        }        return destination;    }    public static void execute(JCoFunction function) {         System.out.println("SAP Function Name : " + function.getName());        try {            function.execute(getDestination());        } catch (JCoException e) {            e.printStackTrace();        }    }public static JCoFunction getFunction(String functionName) {        JCoFunction function = null;        try {            function = getDestination().getRepository().getFunctionTemplate(functionName).getFunction();        } catch (JCoException e) {        e.printStackTrace();        } catch (NullPointerException e) {        e.printStackTrace();        }        return function;    }}
package jco;import com.sap.conn.jco.ext.*;import java.util.HashMap;import java.util.Properties;public class JCOProvider implements DestinationDataProvider,SessionReferenceProvider {    private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();    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()){                    System.out.println("destination configuration is incorrect!");                }                return p;            }            System.out.println("properties is null ...");            return null;        }        catch(RuntimeException re)        {            System.out.println("internal error!");            return null;        }    }    @Override    public void setDestinationDataEventListener(            DestinationDataEventListener eventListener) {        this.eL = eventListener;        System.out.println("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);                eL.updated(destName); // create or updated            }        }    }    public JCoSessionReference getCurrentSessionReference(String scopeType) {        RfcSessionReference sesRef = JcoMutiThread.localSessionReference.get();        if (sesRef != null)            return sesRef;        throw new RuntimeException("Unknown thread:" + Thread.currentThread().getId());    }    public boolean isSessionAlive(String sessionId) {        return false;    }    public void jcoServerSessionContinued(String sessionID)            throws SessionException {    }    public void jcoServerSessionFinished(String sessionID) {    }    public void jcoServerSessionPassivated(String sessionID)            throws SessionException {    }    public JCoSessionReference jcoServerSessionStarted() throws SessionException {        return null;    }}

package jco;import com.sap.conn.jco.ext.JCoSessionReference;import java.util.concurrent.atomic.AtomicInteger;public class RfcSessionReference implements JCoSessionReference {static AtomicInteger atomicInt = new AtomicInteger(0);private String id = "session-" + String.valueOf(atomicInt.addAndGet(1));;public void contextFinished() {}public void contextStarted() {}public String getID() {return id;}}

package jco;public interface IMultiStepJob {public boolean runNextStep();String getName();public void cleanUp();}

package jco;import java.util.Hashtable;import java.util.concurrent.BlockingQueue;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;public class JcoMutiThread extends Thread {public static Hashtable<IMultiStepJob, RfcSessionReference> sessions = new Hashtable<IMultiStepJob, RfcSessionReference>();public static ThreadLocal<RfcSessionReference> localSessionReference = new ThreadLocal<RfcSessionReference>();private BlockingQueue<IMultiStepJob> queue ;private CountDownLatch doneSignal;private boolean isSapBusy = false;public JcoMutiThread(CountDownLatch doneSignal, BlockingQueue<IMultiStepJob> queue) {this.doneSignal = doneSignal;this.queue = queue;}@Overridepublic void run() {try {for (;;) {IMultiStepJob job = queue.poll(10, TimeUnit.SECONDS);// stop if nothing to doif (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);//Thread Started ("Task " + job.getName() + " is started.");try {isSapBusy = job.runNextStep();} catch (Throwable th) {th.printStackTrace();}if(isSapBusy){//sap system busy, try again later("Task " + job.getName() + " is passivated.");queue.add(job);}else{//" call sap finished, Task " + job.getName() ;sessions.remove(job);job.cleanUp();}localSessionReference.set(null);}} catch (InterruptedException e) {// just leave} finally {doneSignal.countDown();}}}



0 0
原创粉丝点击