架构概述

下图显示了基本的OAF状态管理组件的应用开发视图(它并没有反映所有的OAF细节)。

root application module(数据库会话和事务状态)

OAF页面中,每个页面都关联到一个root application module,提供了事务上下文和JDBC数据库连接(在OAF中,数据库会话是关联到JDBC连接的)。

Root application moduleOAF的中枢module,因为核心的应用数据(视图对象、实体对象等)和页面的WEB BEAN结构都自动被它(oracle.apps.fnd.framework.OADBTransaction)缓存。

警告:使用后退按钮可能使APPLICATION MODULE状态丢失。在编写代码之前请参考“支持后退按钮”。

所有存在于事务中的数据对于所有共享这一ROOT APPLICATION MODULE实例的页面都是可访问的。OAF提供了你可以用来从事务中存储、取出、删除数据的方法。一个简单的事务可以被控制器和模型中的代码访问,这些工具是在oracle.apps.fnd.framework.webui.OAPageContext(对于控制器)和OADBTransaction(对于模型)中提供的。

保持ROOT APPLICATION MODULE

默认情况下,当用户从一个页面转到另一个页面时(如一个GET请求或者一个JSP FORWARD),OAF生成一个新页面,前一个页面的application module被释放,一个新的实例从applicaiotn module池中生成。

注意:OAF从不会释放从POST请求提交的application module(除非你手工释放)。如:如果用户对一个表格排序或在表格间跳转(两个在后台提交form的动作)页面的application module实例自动被保持。

保持页面间的APPLICATION MODULE

上面所说的情况适合于单独的、完整的任务。但对于由多页面组成的一个任务或者多个关联页面共用一个事务的情况,不同的页面就必须关联到一个ROOT APPLICATION实例。

达到以上的情况,你必须做到:

l         在多页面中为每个页面指定同一个root application module

l         通过指定URL参数retainAM=Y来设置application module retention标记。对于GET请求,这个标记是在新页面显示的时候被处理的(如上面所提到的,OAF总是为POST请求保持同一个application module,而不管retainAM参数)。如果设为Y,前一个页面的application module会被保留,如果设为N(或者不设,视同为N),OAF会释放所有的application module,包括以前那些显式声明为保留的。

你也可以在JSP FORWARD OAPageContext时设置此参数。

警告:只在不同的页面关联同一个root application module是不够的。如果你忘了设置retainAM标志,每个页面会使用不同的application module实例和事务,即使它们关联到了同一个application module 类型。

注意:典型情况下,根据application module池的状态,页面B 不能得到物理上的页面Aapplication module。但是,对象的状态会完全重置就像建立一个新的一样。你可以认为他是一个新的实例。

同样的,如果你设置了retainAM标志为Y,但是没有将多个页面关联到同一个application module,你的多个页面也会使用不同的application module和事务。

有条件的保留/释放application module

在一些情况下,你可能需要决定是否要保留或释放一个application module。你可以为不同的application module实现oracle.apps.fnd.framework.webui.OAReleaseListener接口。

警告:开发团队没有得到提醒之前,不应该使用这个接口。不正确的使用这个接口会导致内存泄漏。

显式释放application moudule

有时你也会想显式的释放一个root application module,特别地,你在页面控制器中调用OAPageContext.releaseApplicationModule()方法,OAF将会一完成页面显示就释放页面的root application module,而不用等待下一个application module请求。

Root application module保留用例

下表描述了applicatoin module保留或释放的建议

用例

建议

不相关、不连续的任务

当在不相关的不连续的任务页面之间跳转时,你不应该保留application module。如:一系列的相互独立的管理任务。

多页面流

当在同一个任务和事务的多个相关的页面之间跳转时,你应该保留application module

相关页面(虚拟事务)

当在不同任务的使用同一个商务对象的相关页面间跳转(即使这些页面显示不同了不同提交功能),如果页面是关联的,你应该保留application module,如:一个module可以查询、查看、更新、删除、打印采购定单。

不同事务的多个页面

如果是在不同事务的多个页面中,如:你建立一个采购定单时需要建立一个供应商,你应该保留application module在采购定单中,并在建立供应商页面中使用OAPageContext.releaseRootApplicationModule方法

注意:

 

servlet session

如果在JSP基础中提到的,一个servlet session是在一系列HTTP请求的连续动作过程中在浏览器和服务器之间保持状态的的机制。一个session可能在任意时候被应用服务器建立或通过应用、用户关闭浏览器、用户超时来终止。一个session通常对应于一个登录/退出过程,但是在OAF中并不是完全这样。

你可以在servlet session中缓存一个小的可保存的对象(OAF中必须是字符串、数字、日期),同一个session中任何页面都可以访问缓存中的数据。如:如果你认为从数据库中读取用户信息太耗资源了,你可以使用这个方法。

注意:只有当你需要在不同root application module的多个页面中访问一个简单值的时候才需要使用session缓存。你必须记住servlet session数据是没有被清除的(当SESSION激活的时候)必须被显示的清除。这样的话,如果用户没有退出而是简单的中止了,因为没有更好的事件来释放内存,故session是最后一个选择。

提示:有经验的JSP开发者可以会疑惑为什么不用隐藏域,根据OAF当前的菜单实现方法(一些菜单发送GET请求而不是POST请求),所以当你选择一个菜单里,不可能总是向请求中添加值。

如果要在SERVLET SESSION中存储、接收、删除值,查看OAPageContext put*(),get*()remove8()方法。

Oracle应用用户session

当用户登录到OAF中时,OAF建立一个AOL/J oracle.apps.fnd.common.WebAppsContext对象和基于SESSIONcookie,一起保持应用的上下文信息,如当前职责、组织ID和用户信息等。

 

l         Cookie保存了session中的加密的关键信息,这是数据库中的一行数据(特别的,这是一个servlet session id,在已解密的form中,是在ICX_SESSIONS表中的主键)

l         WebAppsContext从每个请求中接收键值,使用它来查询当前的session状态。

l         用户session关联到一个servlet session,但它有自己的生命周期和超时特性。

1.         一般情况下,用户session应该比servlet session生命周期更长。

2.         一个用户session可能关联到多个servlet session(如果,如:当用户在建立一个时间很长的报表过程中,servlet session超时了,然后还可以在用户session超时之前继续工作)。

3.         一个servlet session可能关联到多个用户session(如:一个用户退出,没有关闭窗口又后退)。

l         如果用户session超时了,用户也没有关闭浏览器窗口(基于sessioncookie也没丢失),也没有人删除ICX_SESSIONS表的对应记录,用户就可以在登录后从上次停止的地方继续工作。

如果你需要访问用户session中的数据,你可以OAPageContext(在控制器代码中)或者OADBTransaction(在模型代码中)。

应用上下文

当不能访问OAPageContext时,你也可以使用应用上下文来存储状态(在JAVA 服务器层或者PLSQL代码中)。这样的话,你可以使用WebAppsContext.setSessionArribute(name,value)方法。