⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statefulserverexample.java

📁 jco book to connect java with SAP
💻 JAVA
字号:
import java.io.File;
import java.io.FileOutputStream;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

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.ServerDataProvider;
import com.sap.conn.jco.server.JCoServer;
import com.sap.conn.jco.server.JCoServerContext;
import com.sap.conn.jco.server.JCoServerFactory;
import com.sap.conn.jco.server.JCoServerFunctionHandler;
import com.sap.conn.jco.server.JCoServerFunctionHandlerFactory;

/**
 * This example demonstrate the stateful RFC function modules.
 * To run the example, please create in your SAP System:<br>
 * <ul>
 *  <li>remote enabled function Z_INCREMENT_COUNTER wrapping the INCREMENT_COUNTER<br>
 *      <pre>
 *          FUNCTION Z_INCREMENT_COUNTER.
 *          CALL FUNCTION 'INCREMENT_COUNTER'.
 *          ENDFUNCTION.
 *      </pre>
 *  <li>remote enabled function Z_GET_COUNTER wrapping the GET_COUNTER<br>
 *      <pre>
 *          FUNCTION Z_GET_COUNTER.
 *          CALL FUNCTION 'GET_COUNTER'
 *              IMPORTING
 *                 GET_VALUE = GET_VALUE
 *          .
 *          ENDFUNCTION.
 *      </pre>
 *      with GET_VALUE TYPE  I as export parameter
 *  <li>and report ZJCO_STATEFUL_COUNTER<br>
 *      <pre>
 *          REPORT  ZJCO_STATEFUL_COUNTER.
 *          PARAMETER dest TYPE RFCDEST.
 *          
 *          DATA value TYPE i.
 *          DATA loops TYPE i VALUE 5.
 *          
 *          DO loops TIMES.
 *              CALL FUNCTION 'Z_INCREMENT_COUNTER' DESTINATION dest.
 *          ENDDO.
 *          
 *          CALL FUNCTION 'Z_GET_COUNTER' DESTINATION dest
 *              IMPORTING
 *                 GET_VALUE       = value
 *          .
 *          
 *          IF value <> loops.
 *            write: / 'Error expecting ', loops, ', but get ', value, ' as counter value'.
 *          ELSE.
 *            write: / 'success'.
 *          ENDIF.
 *      </pre>
 * </ul>
 *
 * The function modules are required in this example for repository queries only. 
 * The client side stateful communication is illustrated by the client examples.
 */
public class StatefulServerExample
{
    static String SERVER = "SERVER";
    static String ABAP_AS_WITHOUT_POOL = "ABAP_AS_WITHOUT_POOL";
    static
    {
        Properties connectProperties = new Properties();
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "binmain");
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  "53");
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "000");
        connectProperties.setProperty(DestinationDataProvider.JCO_USER,   "JCOTEST");
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "JCOTEST");
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG,   "en");
        createDataFile(ABAP_AS_WITHOUT_POOL, "jcoDestination", connectProperties);
        
        Properties servertProperties = new Properties();
        servertProperties.setProperty(ServerDataProvider.JCO_GWHOST, "binmain");
        servertProperties.setProperty(ServerDataProvider.JCO_GWSERV, "sapgw53");
        servertProperties.setProperty(ServerDataProvider.JCO_PROGID, "JCO_SERVER");
        servertProperties.setProperty(ServerDataProvider.JCO_REP_DEST, ABAP_AS_WITHOUT_POOL);
        servertProperties.setProperty(ServerDataProvider.JCO_CONNECTION_COUNT, "2");
        createDataFile(SERVER, "jcoServer", servertProperties);
    }
    
    static void createDataFile(String name, String suffix, Properties properties)
    {
        File cfg = new File(name+"."+suffix);
        if(!cfg.exists())
        {
            try
            {
                FileOutputStream fos = new FileOutputStream(cfg, false);
                properties.store(fos, "for tests only !");
                fos.close();
            }
            catch (Exception e)
            {
                throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
            }
        }
    }
    
    
    static class MyFunctionHandlerFactory implements JCoServerFunctionHandlerFactory
    {
        class SessionContext
        {
            Hashtable<String, Object> cachedSessionData = new Hashtable<String, Object>();
        }
        
        private Map<String, SessionContext> statefulSessions = 
            new Hashtable<String, SessionContext>();

        private ZGetCounterFunctionHandler zGetCounterFunctionHandler = 
            new ZGetCounterFunctionHandler();

        private ZIncrementCounterFunctionHandler zIncrementCounterFunctionHandler = 
            new ZIncrementCounterFunctionHandler();
        
        public JCoServerFunctionHandler getCallHandler(JCoServerContext serverCtx, String functionName)
        {
            JCoServerFunctionHandler handler = null;
            
            if(functionName.equals("Z_INCREMENT_COUNTER"))
                handler = zIncrementCounterFunctionHandler;
            else if(functionName.equals("Z_GET_COUNTER"))
                handler = zGetCounterFunctionHandler;
            
            if(handler instanceof StatefulFunctionModule)
            {
                SessionContext cachedSession;
                if(!serverCtx.isStatefulSession())
                {
                    serverCtx.setStateful(true);
                    cachedSession = new SessionContext();
                    statefulSessions.put(serverCtx.getSessionID(), cachedSession);
                }
                else
                {
                    cachedSession = statefulSessions.get(serverCtx.getSessionID());
                    if(cachedSession == null)
                        throw new RuntimeException("Unable to find the session context for session id " + serverCtx.getSessionID());
                }
                ((StatefulFunctionModule)handler).setSessionData(cachedSession.cachedSessionData);
                return handler;
            }
            
            //null leads to a system failure on the ABAP side 
            return null;
        }

        public void sessionClosed(JCoServerContext serverCtx, String message, boolean error)
        {
            System.out.println("Session " + serverCtx.getSessionID() + " was closed " + (error?message:"by SAP system"));
            statefulSessions.remove(serverCtx.getSessionID());
        }
    }

    static abstract class StatefulFunctionModule implements JCoServerFunctionHandler
    {
        Hashtable<String, Object> sessionData;
        public void setSessionData(Hashtable<String, Object> sessionData)
        {
            this.sessionData = sessionData;
        }
    }
    
    
    static class ZGetCounterFunctionHandler extends StatefulFunctionModule
    {
        public void handleRequest(JCoServerContext serverCtx, JCoFunction function)
        {
            System.out.println("ZGetCounterFunctionHandler: return counter");
            Integer counter = (Integer)sessionData.get("COUNTER");
            if(counter == null)
                function.getExportParameterList().setValue("GET_VALUE", 0);
            else
                function.getExportParameterList().setValue("GET_VALUE", counter.intValue());
        }
        
    }

    static class ZIncrementCounterFunctionHandler extends StatefulFunctionModule
    {
        public void handleRequest(JCoServerContext serverCtx, JCoFunction function)
        {
            System.out.println("ZIncrementCounterFunctionHandler: increase counter");
            Integer counter = (Integer)sessionData.get("COUNTER");
            if(counter == null)
                sessionData.put("COUNTER", new Integer(1));
            else
                sessionData.put("COUNTER", new Integer(counter.intValue()+1));
        }
    }
    
    public static void main(String[] args)
    {
        JCoServer server;
        try
        {
            server = JCoServerFactory.getServer(SERVER);
        }
        catch(JCoException ex)
        {
            throw new RuntimeException("Unable to create the server " + SERVER + ", because of " + ex.getMessage(), ex);
        }
        
        server.setCallHandlerFactory(new MyFunctionHandlerFactory());
        
        server.start();
        System.out.println("The program can be stoped using <ctrl>+<c>");
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -