java要调用 SAP RFC接口时,需要用到sapjco3.jar 架包;
windows下还需要将文件sapjco3.dll文件放到system32的目录下;
linux下同样需要把sapjco3.so放入项目的执行目录下;
代码如下;
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: [java] view plain copy 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; } } [java] view plain copy 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; } } [java] view plain copy 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; } } [java] view plain copy package jco; public interface IMultiStepJob { public boolean runNextStep(); String getName(); public void cleanUp(); } [java] view plain copy 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(); } } }