1. 程式人生 > >java呼叫sap的RFC介面

java呼叫sap的RFC介面

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;
	}

	@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);

				//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();
		}
	}
}



相關推薦

Java呼叫https介面get方法,無證書

1.工具類 package springmvc.wx.controller.train; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException;

(二)通過JAVA呼叫SAP介面 (增加一二級引數)

(二)通過JAVA呼叫SAP介面 (增加一二級引數) 一、建立sap連線 請參考我的上一篇部落格 JAVA連線SAP 二、測試專案環境準備 在上一篇操作下已經建好的環境後,在上面的基礎上新增類即可 三、原始碼編寫及測試 首先建立用來傳遞資料的實體類SapData,方便直接取出資料進行下

java呼叫http介面並解析返回的json物件

import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import jav

Java 呼叫webservice介面

方法一: //url為wsdl路徑 public static synchronized boolean sendMsgWebservice(String url,String content,String addresseeTel,String userAccount,String passw

java呼叫WebService介面的一種方法,引數為XML的字串

String xmlinfo = "<data>.......</data>";//xml引數 try { String url = "http://******/Server

Java 呼叫http介面

public static void main(String[] args) throws Exception {        //請求的webservice的url        URL url = new URL("http://");        //建立http連

JAVA 呼叫HTTP介面POST或GET實現方式

package com.yoodb.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.apac

java 呼叫http介面兩種方式

import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Input

使用Java呼叫REST介面時設定超時時間

關於在Java中呼叫REST介面,首先來說一下JAX-RS。JAX-RS是JAVA EE6 引入的一個新技術。JAX-RS即Java API for RESTful Web Services,是一個Java 程式語言的應用程式介面,支援按照表述性狀態轉移(REST)架構風格建

JAVA呼叫http介面

程式碼如下:package demo.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStrea

crf++模型訓練到c++、java呼叫介面

crf模型是個特別好用的模型,做分詞、做ner等nlp工作都力離不開,訓練crf模型用很多工具,比較出名的就是今天要講的crf++,其文件清晰,支援各種語言的介面,本篇blog要講的是c++和java的介面,   這裡java的介面是通過jni呼叫c++實際本質還是c++,不

java呼叫http介面的記錄

最近幾天因為專案需求,做一個門禁管理。而門禁資訊來源則是妙兜。所以我們這邊需要呼叫妙兜的介面,主要是“裝置安裝登記介面”和“鑰匙憑證發放介面”。因為之前沒有做過“java呼叫http介面”類似功能,所以在網上找了很多,也比較久。如下程式碼感覺比較可以,使用過程中也沒出什麼問題

三種方法實現java呼叫Restful介面

1,基本介紹 Restful介面的呼叫,前端一般使用ajax呼叫,後端可以使用的方法比較多,   本次介紹三種:     1.HttpURLConnection實現     2.HttpClient實現     3.Spring的RestTemplat

java呼叫webservice介面 幾種方法

webservice的 釋出一般都是使用WSDL(web service descriptive language)檔案的樣式來發布的,在WSDL檔案裡面,包含這個webservice暴露在外面可供使用的介面。今天搜尋到了非常好的 webservice provide

通過java呼叫Http介面上傳圖片到伺服器

/** * 測試上傳png圖片 * */ public static void testUploadImage(){ String url = "http://localhost:8080/app/remindDetails/doRepair.xht

Java呼叫本地介面java.lang.UnsatisfiedLinkError

 先從一個經典例子說起,Java如何呼叫本地介面。 步驟如下: 1.建立HelloWorld.java class HelloWorld { static{ System.loadLibrary("HelloWorld"); } public native

java 呼叫webservice 介面 解析返回json

public static void main(String[] args)throws ServiceException, MalformedURLException, RemoteExceptio

java呼叫HTTP介面(Get請求和Post請求)

前提: id和name是傳入的引數 瀏覽器訪問介面: java程式碼呼叫Http介面程式碼如下(程式碼中註釋分為兩部分:處理get請求和post請求): package com.inspur.OKHTTP; import java.io.BufferedRe

使用java呼叫http介面

要用到的jar包 使用阿里的fastjson來對json格式資料進行解析 package httpinterface; import java.io.IOException; import org.apache.http.HttpEntity; import org.

Java呼叫第三方介面通過手機號碼查詢運營商和歸屬地

import com.alibaba.fastjson.JSONObject; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; impo