SAP JCO server (SAP inbound) 七步

第一步,环境说明:

SAPJCO,SAP提供的JAVA环境的中间件类库,JAVA的程序可以通过JCO类库,同SAP系统交换数据。

client 工作方式, 中间件叫outbound ( Java call SAP ) the examples  file name:  StepByStepClient.java 

server 工作方式,中间件叫inbound ( SAP call java ) the examples  file name:  StepByStepServer.java 

SAP JCO 地址:http://service.sap.com/connectors

SAP JCO版本 3.0.18 , 官网例子代码文件 StepByStepServer.java,  2018.4.25

我们来调试StepByStepServer.java程序,保留其中的第4个函数,实现sap call  java server.

第二步,SAP系统中的必要参数:

ECC6 EHP6以后,可以动态调整,不用重启SAP服务器就可以生效。

SAP系统中,RZ10里面参数gw/acl_mode的值要0,这样才可以允许运行SM59有注册网关服务。


第三步,SAP系统中,SE37里面定义一个空的RFC调用函数,ABAP内容如下:

*函数名称JCO_SET_TRACE

FUNCTION JCO_SET_TRACE.
*"----------------------------------------------------------------------
*"*"局部接口:
*"  IMPORTING
*"     VALUE(TRACE_LEVEL) TYPE  SY-LISEL
*"     VALUE(TRACE_PATH) TYPE  SY-LISEL
*"----------------------------------------------------------------------
ENDFUNCTION.

第四步,SE38里面做一个ABAP程序来调用上面的空的RFC:

REPORT ZTEST_JCO_SET_TRACE.

DATA trace_level TYPE N.
        DATA trace_path TYPE STRING.

        DATA msg(255) TYPE C.

        trace_level = '555555555'.
        trace_path = '33333333333333.'.

        CALL FUNCTION 'JCO_SET_TRACE'

        destination 'JCO_SERVER'
          EXPORTING
            TRACE_LEVEL = trace_level
            TRACE_PATH = trace_path
         EXCEPTIONS
           COMMUNICATION_FAILURE       = 1
           SYSTEM_FAILURE              = 2 MESSAGE msg
           RESOURCE_FAILURE            = 3
           OTHERS                      = 4.
        IF SY-SUBRC <> 0.
           write: 'ERROR: ',  SY-SUBRC, msg.
        ENDIF.

说明:

1、注意看这个语法,CALL FUNCTION 'JCO_SET_TRACE' destination 'JCO_SERVER'  

它通过JCO_SERVER网关,调用JCO_SET_TRACE函数,然后把这个空RFC函数带的参数数据推到SAP系统外。

2、JCO_SERVER网关怎么来?SM59中自己建一个连接

 3、有一个“注册的服务器程序,程序标识【】”,需要同JAVA 程序配置文件中,server相关参数

中的PROGRAM_ID一致。  这个程序名称,还可以在SAP系统的SMGW事物代码中的登陆客户端信息中看到。

第五步,JAVA程序这块的代码:

精简了官网例子代码文件 StepByStepServer.java

import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.io.File;
import java.io.FileOutputStream;
 
import com.sap.conn.jco.AbapException;
import com.sap.conn.jco.JCoContext;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoFunctionTemplate;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.JCo;
import com.sap.conn.jco.JCoCustomRepository;
import com.sap.conn.jco.JCoListMetaData;
import com.sap.conn.jco.JCoMetaData;
 
import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.ServerDataProvider;
 
import com.sap.conn.jco.server.DefaultServerHandlerFactory;
import com.sap.conn.jco.server.JCoServer;
import com.sap.conn.jco.server.JCoServerContext;
import com.sap.conn.jco.server.JCoServerContextInfo;
import com.sap.conn.jco.server.JCoServerErrorListener;
import com.sap.conn.jco.server.JCoServerExceptionListener;
import com.sap.conn.jco.server.JCoServerFactory;
import com.sap.conn.jco.server.JCoServerFunctionHandler;
import com.sap.conn.jco.server.JCoServerState;
import com.sap.conn.jco.server.JCoServerStateChangedListener;
import com.sap.conn.jco.server.JCoServerTIDHandler;
 
public class StepByStepServer
{
    static String SERVER_NAME1 = "SERVER";
    static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL";
    static String DESTINATION_NAME2 = "ABAP_AS_WITH_POOL";
 
 
	static  
		{
		Properties connectProperties = new Properties();
		connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST,"10.0.3.51");
		connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,"00");
		connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT,"100");
		connectProperties.setProperty(DestinationDataProvider.JCO_USER,"60489");
		connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD,"********");
		connectProperties.setProperty(DestinationDataProvider.JCO_LANG,"ZH");
 
		createDataFile(DESTINATION_NAME1, "jcoDestination",connectProperties);
		connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");
		connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");
 
		createDataFile(DESTINATION_NAME2, "jcoDestination",connectProperties);
 
		Properties servertProperties = new Properties();
		servertProperties.setProperty(ServerDataProvider.JCO_GWHOST,"10.0.3.51");
		servertProperties.setProperty(ServerDataProvider.JCO_GWSERV,"3300");
		servertProperties.setProperty(ServerDataProvider.JCO_PROGID,"JCO_SERVER");
		servertProperties.setProperty(ServerDataProvider.JCO_REP_DEST,"ABAP_AS_WITH_POOL");
		servertProperties.setProperty(ServerDataProvider.JCO_CONNECTION_COUNT, "2");
		createDataFile(SERVER_NAME1, "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 thedestination file " + cfg.getName(), e);
			}
 
		 }
	 } 
	 
    
    
    /**
     * The following server example demonstrates how to develop a function module available only on Java side. At first
     * we create the respective function meta data, because the function is not available in ABAP DDIC. Then the function
     * meta data is stored in a custom repository which is registered with the server instance. Naturally we also
     * need the implementation of the function - see the class SetTraceHandler. 
     * 
     * Last but not least, the following ABAP report invokes the function module SetTraceHandler.
        REPORT  ZTEST_JCO_SET_TRACE.
        
        DATA trace_level TYPE N.
        DATA trace_path TYPE STRING.
        DATA msg(255) TYPE C.
        
        trace_level = '5'.
        trace_path = '.'.
        
        CALL FUNCTION 'JCO_SET_TRACE' destination 'JCO_SERVER'
          EXPORTING
            TRACE_LEVEL = trace_level
            TRACE_PATH = trace_path
         EXCEPTIONS
           COMMUNICATION_FAILURE       = 1
           SYSTEM_FAILURE              = 2 MESSAGE msg
           RESOURCE_FAILURE            = 3
           OTHERS                      = 4
                  .
        IF SY-SUBRC <> 0.
           write: 'ERROR: ',  SY-SUBRC, msg.
        ENDIF.     
     */
 
    
    static class MyFunction implements JCoServerFunctionHandler
    {
        public void handleRequest(JCoServerContext serverCtx, JCoFunction function)
        {
            int level = function.getImportParameterList().getInt("TRACE_LEVEL");
            String path = function.getImportParameterList().getString("TRACE_PATH");
 
            System.out.println("A:" + level + " B:"+ path);
          //  JCo.setTrace(level, path);
        }
    }    
 
 
    public static void main(String[] a)
    {
 
       
        JCoListMetaData impList = JCo.createListMetaData("IMPORTS");
        impList.add("TRACE_LEVEL", JCoMetaData.TYPE_NUM, 1, 2, 0, null, null, JCoListMetaData.IMPORT_PARAMETER, null, null);
        impList.add("TRACE_PATH", JCoMetaData.TYPE_STRING, 8, 8, 0, null, null, JCoListMetaData.IMPORT_PARAMETER, null, null);
        impList.lock();
        JCoFunctionTemplate fT = JCo.createFunctionTemplate("JCO_SET_TRACE", impList, null, null, null, null);
 
		JCoCustomRepository cR = JCo.createCustomRepository("MyCustomRepository");
        cR.addFunctionTemplateToCache(fT); //Repository add FunctionTemplate
        
        JCoServer server ;
 
		try
        {
            server = JCoServerFactory.getServer(SERVER_NAME1); //create server
        }
        catch(JCoException ex)
        {
            throw new RuntimeException("Unable to create the server " + SERVER_NAME1 + " because of " + ex.getMessage(), ex);
        }
       
        
        String repDest = server.getRepositoryDestination();
		System.out.println("repDest:"+ repDest);
 
        if(repDest!=null)
        {
            try
            {
                cR.setDestination(JCoDestinationManager.getDestination(repDest)); //Repository setDestination
            }
            catch (JCoException e) 
            {               
            }
        }
		
        server.setRepository(cR); //server add Repository
        
        
        JCoServerFunctionHandler myf = new MyFunction();
        DefaultServerHandlerFactory.FunctionHandlerFactory factory = new DefaultServerHandlerFactory.FunctionHandlerFactory();
        factory.registerHandler(fT.getName(), myf);
        server.setCallHandlerFactory(factory);
        
        server.start();
        System.out.println("The program can be stoped using <ctrl>+<c>");
    }
}

程序说明:

1、连接SAP服务器的参数配置,有client和server。 

client程序运行:用于java程序同SAP服务器按SAP的协议建立的长SOCKET连接。

server程序:等待SAP对java程序的调用,一旦SAP的JCO_SET_TRACE发起调用,数据就会在JAVA对应的程序中接收。

可以看到,JCO_SET_TRACE函数发了2个最简单的参数变量数据过来。

2、JAVA SAPJCO类库,Repository对象,function对象,IMPORTS对象,TABLE对象等等,同ABAP RFC是对应的。

第六步,我们从SAP传2个变量数据到JAVA:

上面我们先打开我们的java server程序.

执行SAP端的ABAP程序,发起调用。

可以看到,SAP的2个变量5555,3333333333333 传到了JAVA程序中,并显示了出来。

(为啥只显示一个5,ABAP用的string, JAVA是用的int,还没来得及改)

真实场景中传结构(一行数据),表(多行数据),接收相应参数即可。

第七步,监控:

事务代码SMGW,可以看到JAVA和SAP建立的长连接。

一旦长连接建立,SAP系统中还可以在SM59中测试连接延迟。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值