大家好,关于SAP接口开发教程:JCo 3.0会话管理篇很多朋友都还不太明白,今天小编就来为大家分享关于的知识,希望对各位有所帮助!
1. JCoContext
如果SAP 中的多个函数需要在一个会话中运行,则需要JCoContext 提供保证。如果在同一个线程中,一般模式如下:
JCoContext.begin(sapDestination);
fm1.execute(sapDestination);
fm2.execute(sapDestination);
JCoContext.end(目的地); begin()和end()之间的函数执行完毕后,SAP不会释放连接,以确保处于同一个会话中。
第二种情况:如果不同的功能不在同一个线程中,开发人员需要实现SessionReferenceProvider接口并在类中提供会话id。逻辑与nco3.0相同。 JCo3.0提供了示例代码,但过于复杂。为了方便理解,我做了一个简单的。
2. SAP函数
我们要使用的函数来自标准系统函数INCREMENT_COUNTER
,从GET_COUNTER 复制。 SAP系统中的INCRMENT_COUNTER
、GET_COUNTER在同一个函数组中,共享一个变量count(计数器),每次运行INCRMENT_COUNTER
,count会加一,GET_COUNTER函数
可以得到这个计数。因为这两个函数无法远程调用,所以我们将这两个函数复制到另外两个函数ZINCRMENT_COUNTER和ZGET_COUNTER中。
3. 同一线程中执行函数
首先我们在类RfcFunctions 中定义两个函数:
包jco3.demo6;
导入com.sap.conn.jco.JCoDestination;
导入com.sap.conn.jco.JCoException;
导入com.sap.conn.jco.JCoFunction;
公共类RfcFunctions
{
public static int runGetCounter(JCoDestination dest) 抛出JCoException
{
JCoFunction counterFM=dest.getRepository().getFunction("ZGET_COUNTER");
counterFM.execute(dest);
int counter=(int) counterFM.getExportParameterList().getValue("GET_VALUE");
退货柜台;
}
public static void runIncrement(JCoDestination dest) 抛出JCoException
{
JCoFunction 增量=dest.getRepository().getFunction("ZINCRMENT_COUNTER");
增量.执行(dest);
}
}然后编写一个测试类进行测试:
包jco3.demo6;
导入com.sap.conn.jco.JCoContext;
导入com.sap.conn.jco.JCoDestination;
导入com.sap.conn.jco.JCoDestinationManager;
导入com.sap.conn.jco.JCoException;
公共类TestSessionSameThread
{
public static void main(String[] args) 抛出JCoException、InterruptedException
{
//获取JCoDestination 对象实例
JCoDestination 目的地=JCoDestinationManager.getDestination("ECC");
//确保这两个函数将在同一个会话中执行
JCoContext.begin(目的地);
//增量之前
System.out.println("执行ZINCRMENT_COUNTER: 之前");
System.out.println("Counter:" + RfcFunctions.runGetCounter(destination));
//运行incrementCounter五次
for(int i=0; i 5; i++){
RfcFunctions.runIncrement(目的地);
System.out.println("Add:" + (i + 1));
}
//增量后
System.out.println("执行ZINCRMENT_COUNTER:后");
System.out.println("Counter:" + RfcFunctions.runGetCounter(destination));
//释放连接
JCoContext.end(目的地);
}
}代码很直观,就不多说了。函数执行前,counter的值为0。函数运行5次后,counter的值为5。如果我们注释掉JCoContext.begin(destination);和JCoContext.end(destination);我们可以比较不同的效果。
4. 不同线程中执行函数
如果不同的函数在不同的线程中执行,开发者需要提供session id。我将把这两个函数放在不同的线程中:
在JVM主线程中调用ZGET_COUNTER查看计数器的结果。在另一个线程中运行ZINCRMENT_COUNTER,两个线程通过JCoContext 保持在相同的会话ID 下。
4.1 实现JCoSessionReference接口
JCoSessionRefence实现类的主要功能是提供会话ID:
包jco3.session;
导入java.util.concurrent.atomic.AtomicInteger;
导入com.sap.conn.jco.ext.JCoSessionReference;
公共类JCoSessionRefenceImpl 实现JCoSessionReference
{
私有AtomicIntegeratomInt=new AtomicInteger(0);
private String id="session"+String.valueOf(atomInt.addAndGet(1));
公共无效上下文完成()
{
}
公共无效上下文启动()
{
}
@覆盖
公共字符串getID()
{
/**
* 我们需要重写getID()方法
*/
返回ID;
}
}
4.2 实现SessionReferenceProvider接口
在SessionReferenceProvider接口的实现类中,重写getCurrentSessionReference()方法,获取上面定义的JCoSessionRefence来获取会话ID。其他方法不变。
包jco3.session;
导入com.sap.conn.jco.ext.JCoSessionReference;
导入com.sap.conn.jco.ext.SessionException;
导入com.sap.conn.jco.ext.SessionReferenceProvider;
公共类SessionReferencProviderImpl 实现SessionReferenceProvider
{
@覆盖
公共JCoSessionReference getCurrentSessionReference(字符串范围类型)
{
/**
* 我们需要重写getCurrentSessionReference() 方法
*/
JCoSessionRefenceImpl sessionRef=new JCoSessionRefenceImpl();
返回会话引用;
}
@覆盖
公共布尔isSessionAlive(String sessionID)
{
返回假;
}
public void jcoServerSessionContinued(String sessionID) 抛出SessionException
{
}
公共无效jcoServerSessionFinished(字符串会话ID)
{
}
public void jcoServerSessionPassivated(String sessionID) 抛出SessionException
{
}
public JCoSessionReference jcoServerSessionStarted() 抛出SessionException
{
返回空值;
}
}
4.3 注册 SessionReferenceProvider接口
注册SessionReferenceProvider接口的实现类,使JCoDestination具有状态管理功能。
包jco3.session;
导入com.sap.conn.jco.JCoDestination;
导入com.sap.conn.jco.JCoDestinationManager;
导入com.sap.conn.jco.JCoException;
导入com.sap.conn.jco.ext.Environment;
导入com.sap.conn.jco.ext.SessionReferenceProvider;
公共类DestinationProvider
{
公共静态JCoDestination getDestination() 抛出JCoException
{
//创建SessionReferenceProvider 的实例
//并在环境中注册
SessionReferenceProvider 提供者=new SessionReferencProviderImpl();
环境.registerSessionReferenceProvider(提供者);
JCoDestination 目的地=JCoDestinationManager.getDestination("ECC");
返回目的地;
}
}
4.4 在单独线程中执行ZINCREMENT_COUNTER
定义WorkingThread,继承Thread类,并在该线程中执行函数ZINCRMENT_COUNTER 5次。
包jco3.demo6;
导入com.sap.conn.jco.JCoDestination;
导入com.sap.conn.jco.JCoException;
公共类WorkingThread扩展Thread
{
私人布尔完成信号;
私有JCoDestination 目的地;
//构造函数
公共工作线程(JCoDestination目的地,布尔doneSignal)
{
this.destination=目的地;
this.doneSignal=didSignal;
}
公共布尔值hasDone()
{
返回完成信号;
}
@覆盖
公共无效运行()
{
/**
* runIncrement()方法运行五次
*/
for (int i=0; i 5; i++){
尝试{
RfcFunctions.runIncrement(this.destination);
System.out.println("运行" + (i+1) + "次。");
} catch (JCoException e) {
e.printStackTrace();
}
}
this.doneSignal=true;
}
}doneSignal 用于标识线程是否结束。当run() 方法完成时,线程本身结束。
4.5 测试多线程函数调用
好的,最后我们测试一下多线程下的函数调用:
包jco3.demo6;
导入com.sap.conn.jco.JCoContext;
导入com.sap.conn.jco.JCoDestination;
导入com.sap.conn.jco.JCoException;
导入jco3.session.DestinationProvider;
公共类TestSAPSessionMultiThread
{
public static void main(String[] args) 抛出JCoException、InterruptedException
{
/**
* 运行ZINCRMENT_COUNTER ZGET_COUNTER 函数
* 以有状态的方式处理不同的线程。
*
* SAP 将保留创建的会话ID
* JCoSessionReferenceImpl 类
* 并在SessionReferenceProviderImpl 类中使用。
*
* 使用前,SessionReferenceProviderImpl类应该是
* 使用Environment.registerSessionReferenceProvider()方法注册。
*/
//获取JCoDestination 对象实例
JCoDestination 目的地=DestinationProvider.getDestination();
//确保这两个函数将在同一个会话中执行
JCoContext.begin(目的地);
//增量之前
System.out.println("执行ZINCRMENT_COUNTER: 之前");
System.out.println("Counter:" + RfcFunctions.runGetCounter(destination));
//启动一个新线程,其中函数ZINCRMENT_COUNTER
//将执行五次
工作线程工作线程=新工作线程(目的地,假);
工作线程.start();
//等待并切换线程
线程睡眠(1000);
//增量后
if (workingThread.hasDone()==true){
System.out.println("执行ZINCRMENT_COUNTER:后");
System.out.println("Counter:" + RfcFunctions.runGetCounter(destination));
}
//释放连接
JCoContext.end(目的地);
}
}与之前同一线程中的代码的主要区别是:
定义WorkingThread类的实例并启动线程:
【SAP接口开发教程:JCo 3.0会话管理篇】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
想了解JCo3.0怎么管理会话,这篇文章挺关键啊~
有6位网友表示赞同!
看这标题就知道是SAP接口的专业内容了,俺对这种太菜皮了~
有19位网友表示赞同!
希望文章讲明白会话的建立和销毁方法,以及一些常见的错误处理!
有8位网友表示赞同!
最近我刚接触JCo3.0,这个系列文章正好能帮到我。
有14位网友表示赞同!
SAP接口编程对我来说还是一门新的技术,学习起来不容易啊~
有5位网友表示赞同!
感觉这篇文章的内容很有深度,适合有一定基础的人来阅读。
有7位网友表示赞同!
作者的技术水平很高,期待他的解析和案例讲解!
有6位网友表示赞同!
希望能详细介绍不同类型的会话管理方法。
有16位网友表示赞同!
文章的标题很明确,让人很容易了解文章的内容范围。
有20位网友表示赞同!
JCo3.0的功能更新很多,学习起来确实需要花时间积累经验。
有14位网友表示赞同!
对于SAP开发,接口编程是必不可少的技能。
有7位网友表示赞同!
这个系列文章能帮我掌握更丰富的SAP接口知识!
有12位网友表示赞同!
希望以后还有更多关于JCo3.0的教程和案例分析。
有18位网友表示赞同!
学习技术的最终目的是为了解决实际问题,这篇文章应该很有实用价值。
有11位网友表示赞同!
对于像我这样想要成为SAP开发工程师的人来说,这个系列文章非常有帮助!
有11位网友表示赞同!
感谢作者分享这些宝贵的知识和经验。
有20位网友表示赞同!
我已经收藏了这篇文章,等我有空的时候再仔细阅读!
有13位网友表示赞同!