OAF状态管理

http://blog.sina.com.cn/s/blog_5390f8d20100pvyj.html

http://blog.sina.com.cn/s/blog_5390f8d20100pvyi.html
http://blog.sina.com.cn/s/blog_5390f8d20100pvyj.html


OAF文档五:OAF状态管理(一)

(2006-04-18 16:16:41)
标签:

杂谈

分类:MSN搬家

OAF状态管理

架构概述

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

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

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

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

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

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

保持ROOT APPLICATIONMODULE

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

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

保持页面间的APPLICATIONMODULE

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

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

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

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

你也可以在JSPFORWARDOAPageContext时设置此参数。

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

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

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

有条件的保留/释放applicationmodule

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

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

显式释放applicationmoudule

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

Root application module保留用例

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

用例

建议

不相关、不连续的任务

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

多页面流

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

相关页面(虚拟事务)

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

不同事务的多个页面

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

注意:

 

servlet session

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

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

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

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

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

Oracle应用用户session

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

 

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

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

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

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

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

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

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

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

应用上下文

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

OAF文档五:OAF状态管理(二)

(2006-04-18 16:21:46)
标签:

杂谈

分类:MSN搬家

页面上下文

每次接收到一个页面的请求,OAF都建立一个OAPageContext存储信息,直到新的页面完成(特别的,OAPageBean建立OAPageContext,它主要是在页面后台起做作)

请求和页面边界

一个WEB应用的工作单元是一对请求/响应,浏览器发送请求,servlet处理这个请求并返回一个响应,响应的传送意味着一个请求的结束,或者是一个请求的完成与新的请求之前的分界。

同样,当OAPageBean完成页面的处理,这也是当前页面与新页面之间的分界。

所以,一个用户从页面X跳转到页面A,又跳转到页面B,这时我们有两个请求边界:XA之间,AB之间。也有两个页面边界:XAAB

 

有些情况下,请求和页面的边界不相同,考虑以下情况:

用户从XA

A的时候,在响应决定显示哪个页面之前,用户选择了A的控件,所以,浏览器发送了一个请求到A,当A处理结束,就达了第一个页的边界。

在页面A的代码中,开发者估算用户选择了哪个控件发送JSPFORWARD到页面B,因为我们不想重新显示A,所以不用反回HTTP响应,OAF开始处理页面B(包括建立一个新的OAPageContext),一旦B处理完成,就到达了第二个页面边界。

因为页面B必须显示给用户,故一个HTTP响应发送到浏览器,就到了请求的边界。

 

基于以下的原因,明白这一点是很重要的

l        请求参数存在于请求的生命周期中,它可以跨越多个页面的边界。这对于那些认为一个请求和一个页面相同的开发者来说有点奇怪,在JSPFORWARD后也不用说明请求参数还存在。如以下示例:

1.        用户选择了页面X中的连接,转到页面A,页面AURL包括参数foo=bar

2.        页面A发送一个到页面BJSPFORWARD,现在即使我们是在一个新的页面中,请求中仍然包括foo=bar

3.        如果你不想在jspforward后还包括参数,你必须显式的覆盖它(注意你不能从请求中删除参数),如当你调用OAPageContextsetForward方法时你可以重置参数,foo=X

提示:将不需要的参数设为一个新值更可取,不要简单地将它设为“”。

l        因为在页面上下文与请之前没有一对一的关系,对于从OAPageContext中访问请求参数,有人会感到疑惑。只要记得每个页面是一个明确的实体,从它的“显示点”OAPageContext表示了一个请求。

l        当你进入上图的细节时,你会看到页面与请求的边界是明确的有不同含义的钝化事件点。

请求

尽管是生命周期很短,每个HTTP请求还是建立一个对象。这个对象包括以下应用状态:

所有的URL参数,不管是POST还是GET

如果是POST请求,包括FORM中的数据。

如果是POST请求,webbean和事件名称会关联到用户选择的控件(如用户选择了一个GO按钮,请求会包括以这个按钮命名的webbean,所以你可以知道它被按下了并以此做出响应)。

为了访问请求值,使用OAPageContextgetParameter*()方法。

使用隐藏域

一个隐藏域是开发者在FORM中读取或写入数据工具,它不能被用户访问。如同用户看到的FORM域一样,隐藏域也在提交时被加到了请求中。

你可以通过在Jdeveoper中选择itemstyleformValue建立一个隐藏域。在运行时,它以oracle.apps.fnd.framework.webui.beans.form.OAFormValueBean来初始化。

JSPFORWARD和重定向时指定值

当你显式的使用OAPageContextsetForward*()或者OAPageContext.sendRedirct()方法转到一个新的页面时,你可以设定请求参数。

例如:假定有一个页面包括一个提交按钮,当用户点击时,我们想使用JSPFORWARD转到B页面。页面A需要一传递一个mode值给页面B(可以由不同的方式来访问),所以它知道如何做。

1、 用户点击提交按钮。

2、 在页面A的控制器中处理这个按钮,在processFormRequest方法中调用OAPageContext.setForwardURL()。做为一个方法调用,设定参数queryMode=automatic

3、 在页面B的控制器中,在processRequest方法中检查参数queryMode值,调用getParameter(“queryMode”)

4、 页面B控制器于是响应queryMode参数值为automatic,查询数据来显示页面。

调用OAPageContext.putParameter()指定值

OAPageContext包括putParameter()方法,在页面处理过程中,你可以用来传递值到webbean结构中,或者使用jspforward从一个页面传到下一个页面。如:一个顶层的region可能放置一个值到缓存中,它的子region可以引用。

提示:这个和JAVA SERVLET2.1HttpServletRequest.setAttibute()方法很相似,可以认为它们做用相同。

设定URL参数

当在Jdeveloper中定义URL时你可以指定请求参数,或者在相关的程序中设置URL

警告:URL是有长度限制的,你应该小心的添加URL参数的数量,尤其是很长的时候。因为URL是可见的,你应该加密敏感的值,然后再解密。

状态钝化模型(“Passivation”)

OAF是事务导向的,许多事务都跨越了多个页面。这些事务需要一定的状态来保存信息直到用户完成任务。如:一个建立采购定单的的流程中,用户在第一页描述定单,在第二页输入一个或多个项目,在第三页提交前检查信息,这个采购定单数据在每个浏览器提交的请求之间必须被保存。

HTTP协议是无状态的,它不能保存任何指定的状态也不保证支持状态保存。而且,如果提供servletsessionJVM实例失败了,或者servletsession超时了,应用状态就丢失了,等待的事务也不能恢复。

OAF,从另一方面来讲,当用户工作时,合并了保存与恢复客户端状态的能力,即使是servletsession超时(以后的版本会提供JVM失败的支持)。

l        保存应用状态到另一个地方(在OAF中,是保存在数据库中)叫做钝化。

l        从其它地方恢复应用状态叫做活化。

特别的,OAF目前提供了以下的状态管理特点:

可变的应用,当资源消耗很高时,OAF保存空闲线程的状态,并将它们的资源重新分配给其它线程,而不是新建一个资源实例。当空闲的线程激活时,保存的状态被恢复。简单说,资源会在JDBC连接、applicationmodules、用户session中重新分配。

Servlet session超时恢复,servletsession会超时,而不用用户重新开始一个未完成的事务(将来这个特点会扩展到提供中间层的失败支持)。

Application module缓冲池

为了提高性能和可变性,OAF缓冲了APPLICATIONMODULE,重用是比重建更有效的方式。在简单的情况下:

l        每个JVM都有一个applicationmodule池管理器,里面包含和管理不同的applicationmodule池。

l        每个applicationmodule池包含了一些applicationmodule的实例,如,如果一个应用使用了两个root applicationmodule,就有两个applicationmodule池:oracle.apps.fnd.framework.toolbox.tutorial.server.Lession3AMoracle.apps.fnd.framework.toolbox.tutorial.server.Lession4AM,如下图。换句话说,每个root applicationmodule都建立一个池。

l        在池中的applicationmodule实例被设计成可用的或者不可用的(当前被提取走的)。

l        只有root applicationmodule是放在池中的,嵌套的applicationmodule是被root applicationmodule缓冲的。




http://www.2cto.com/database/201109/102483.html

页面基础
在浏览器层,OAF页面和其它页面一样,是标准的HTML页面。
在中间层,OAF页面实际是由内存中的JAVABEAN结构来实现的,和传统的JAVA客户端界面相同。每个页面中的用户界面(UI)组件(按钮、标签、图片等)实际都对应一个或多个结构中的JAVABEAN。
当浏览器请求一个新页面时,OAF读取页面中的声明的元数据来建立WEB BEAN的结构。对每一个带有UI控制器的BEAN,OAF调用你写的代码来初始化页面。当页面执行完毕,OAF将WEBBEAN结构交给UIX框架来处理,它能将之转为HTML发送到浏览器。
当浏览器提交一个FORM(如:用户选择了搜索区的GO按钮),如有必要,OAF重新建立WEBBEAN结构(BEAN结构在请求之间是缓存了的,只有在意外的情况下需要重新建立),然后调用你在PAGEBEAN中写的处理事件的代码。当页面处理结束,HTML页面重新建立并发送到浏览器。
模型
模型封装了指定的应用中的数据和商业逻辑。它也提供了真实的商业对象和商务服务的抽象。
注意:要完全正确和一致,本图需包括以下的实现
oracle.apps.fnd.framework.server.OADBTransactionImpl而不是oracle.apps.fnd.framework.OADBTransaction接口。
Application Modules
一个BC4J应用模型是管理和提供BC4J模型对象的基础容器,在这个上下文中,同一任务的对象是由多方关联的。例如:所有的BC4J对象都包含一个相同任务的事务。甚至用户界面包括多个页面。
所有的APPLICATION MODULE都是oracle.apps.fnd.framework.server.OAApplicationModuleImpl的子类。
每一个OAF页面都有一个关联到顶层REGION(pageLayout region)的ROOT application module。这个root application module提供了事务处理的上下文,封闭了数据库的连接。
l         如果多个页面在一个事务中,它们应该共享一个root application module。
l         如果一个页面和其它页面没关系,它应该有自己的application module。
注意:一个root application module可能嵌套多个application module(也可以再嵌套多层)。在这种情况下,root application module可以访问它所嵌套的所有的数据、对象和所有的ROOT包含的参与同一个事务的子对象。你可以在你想创建重用的与数据库交互的UI region时使用这个特点。
Entity Objects(和Association Objects)实体和关联实体
BC4J实体封装了关联到数据表行的商务规则(验证、动作等)。如:OAFSample Library包括了FWK_TBX_SUPPLIERS表,用来存储供应商的定义。我们可以为这个表定义一个实体对象(SupplierEO),用来实现的所有的商业规则,新建、更新、删除一个供应商。
注意:Entity Object也可以基于视图、同义词和快照。
OAF支持JAVA和PLSQL实体。
你建立的大多数实体都应该是oracle.apps.fnd.framework.server.OAEntityImpl的子类。
在数据库和实体之间是一对一的关系,所有的ORACLE Applicaiotn 实体都应该包括它们关联的表的所有列。实体使用声明来在它们的属性和指定的数据列之间映射,来自动实现查询、插入、更新和删除。大多数情况下,你需要添加验证逻辑。
实体可以被任何需要与表交互的程序使用(不仅是OAF),这样一来,就必须考虑到所有的验证规则以便客户端就不用再关注这些了。
Association Objects(关联实体)
如果你有一个复杂的实体(如三层采购定单,在头、行、发运地之前是一对多的关系),你可以使用association object来定义实体间的关系,你可以定义弱连接(一个定单引用了已经存在的供应商)和强连接(一个定单包括它的行,行不能独立于头存在)。
View Objects(and view Links)视图对象和视图连接
在简单的情况下,一个BC4J视图对象封装了一个数据库查询。查询执行后,一个视图对象循环访问结果集。结果集包含一个或多个视图行,一个视图行的不同属性对应数据库查询的行。
所有的视图对象都是oracle.apps.fnd.framework.server.OAViewObjectImpl的子类。
每个视图对象都可以配置用以下的方法来查询数据:
1、属性对应SQL语句的列(通常用于较小、只读的视图对象)
2、属性对应实体对象的属性(用于插入、更新、删除实体对象)
3、一些属性对应到实体,一些属性直接对应SQL(用来增强实体对象的不能从实体对象查询的临时数据,如显示的计算值)。
在OAF中,在下面的情况下会用到视图对象。
l         为详细的用户界面展示最优化的数据。如果用户界面支持实体对象的插入、更新、删除,你应该使用视图对象来完成这些任务。
l         为建立下拉列表建立查询,值列表和其它的界面组件。
l         为商业逻辑建立有效的“验证查询”。如:在采购定单头实体对象中,你可能要使用一个验证视图对象来取得这个采购定单的最大行号,以便于它可以被缓存而在新行插入时可以增加。
最后,你可能不只需要定义视图对象,还可能要为它们编写代码。典型情况下,代码应该实现复杂的查询的数据绑定并执行查询(所以视图对象知道如何查询它自己)。
视图连接
就像连接实体对象一样,你也可以创建视图对象的关联,这叫做视图连接。如:你在采购定单头视图对象和行视图对象之间建立了一个视图连接,这可以用来在访问头的时候自动查询行。
OADBTransaction
如上图所示:OADBTransaction在你的模型中的一个中心角色,它封装了JDBC的数据库连接会话和root application module的关联。并且直接容纳了你建立的所有实体对象(视图对象由root application module容纳,并在视图行中引用了实体对象)。你将在你的模型中正常使用OADBTransaction,基于以下原因:
l         建立callable statement来执行PLSQL函数的过程。
l         访问session级别的应用上下文,如用户名、id、当前职责等。
l         如果需要执行NLS操作,如转换服务器时间格式为用户时间格式,访问oracle.apps.fnd.framework.OANLSServices对象
root application module可以访问OADBTransaction。
视图
视图用来为用户格式化和显示模型数据。
定义页面
在设计时,你可以使用声明的方式来建立BEAN的结构。在oracle开发过程中,你将对XML文件进行定义。当你部署到客户站点时,OAF从数据库中运行页面定义。
为了简单说明,Jdeveoper定义的页面由REGION和ITEM组成。
l         ITEM是一个简单的组件,如按钮、输入框、图下等不包括子元素的组件。
l         REGION是包括ITEM的容器。如:header、表格或特定的布局组件。
l         你定义的每个REGION和ITEM都有一个STYLE属性,用来指明OAF在运行时使用哪个WEB EBAN对象来为它实例化(这会指明产生什么要瓣HTML代码),如:如果你定义了一个STYLE为table的REGION,OAF会用oracle.apps.fnd.framework.webui.beans.table.OATablebean来实例化。
l         所有的页面必须包含一个顶层的REGION(叫做root region),它的STYLE是pageLayout,它是oracle.apps.fnd.framework.webui.beans.layout.OAPageLayoutBean的实例。
l         在Jdeveoper的页面树中的REGION和ITEM的顺序指明了在运行时添加BEAN结构的位置。
下图显示了一个简单页面的WEB BEAN显示效果,你看到的页面的标签指明了WEB BEAN的名字。如:一个下拉列表是oracle.apps.fnd.framework.webui.beans.message.OAMessageChoiceBean的实例,一个提交按钮是oracle.apps.fnd.framework.webui.beans.form.OASubmitButtonbean的实例。
 
注意:下面图中的ITEM名称没有按照ORACLE应用命名标准来做,只是让你明白WEB BEAN的结构。
 
Attribute Sets 属性集
每个REGION和ITEM都可以使用属性集来继承一组属性,一个属性集是经过命名可重用的属性的集合,它可以被任何UI对象使用,包括region\item和其它属性集。无论何时你建立一个使用属性集的UI组件,你都可以覆盖它的继承的属性(尽管这在OAF中是不推荐的)。
为了说明这一点,在应用开发中,每个表格必须为他的每一列关联到属性集,这些属性集如提示标签、显示宽度等。
l         在OAF的ToolBox示例中,有一个采购定单表(FWK_TBX_PO_HEADERS),HEADER_ID是NUMBER类型的主键,也作为采购定单号显示。
l         这个表格有一个关联的属性集:FwkTbxHeaders,是一个XML包文件,里面包括了所有的表列的属性(每一列一个属性)。其中一个属性叫做HeaderId。
l         HeaderId属性设置Prompt为 Order Number,Display Length为15。
l         当我们建立一个页面包括采购定单的order number 这个ITEM时,我们也应该指定属性集为/oracle/apps/fnd/framework/toolbox/attributessets/FwkTbxheaders/Headerid
 
组件重用
如果想组合页面中的共享对象,你可以简单的继承它们
如:在OAF的ToolBox示例中,我们建立了一个通用的REGION(叫PoSummaryRN),所以这个组件可以被多个页面包含而不用重写代码。要添加一个region到页面,我们只要简单的建立一个新的region,将Extends属性设为:/oracle/apps/fnd/framework/toolbox/tutorial/webui/PoSummaryRN
注意:这个共享的REGION在引用它的页面中是不能修改的,所以在Jdeveloper的Structure面板中的灰色的。
 
数据源绑定
对于有数据库交互(插入、更新、删除、查询)的BEAN,你还要指定一个数据源绑定到一个视图实例和关联的视图属性名称。这个绑定非常重要,因为OAF用它来查询数据、写回用户输入的数据。
l         View Instance Name指的是在application module中的视图对象(所有的视图对象都存活于application module中并通过它们的名称来调用),如:如果一个SuppliersVO视图对象由页面中的root application module通过“MySupVO”来调用,则在这里你应该指定MySupVO这个名字。
l         View Attribute Name 指的是映射到列的视图属性。如:如果你的SuppliersVO有一个属性“SupplierId”(映射到列SUPPLIER_ID),这里你应该指定“SupplierId”这个名称。
定义菜单
你应该使用oracle application菜单和功能的表单中定义菜单。
正像OAF将定义的UI布局翻译成运行时的BEAN结构,它也包含了菜单定义的WEB BEAN。
定义页面流
处理多页面事务流时,OAF提供了一个可定义的(可客户化)给复杂的、硬编码的控制逻辑。
客户化页面
OAF也包括了一个可定义的客户化架构,叫做:OA Personalization Framework。这是为了支持最终用户所需的客户化和产品传输链(区域化和垂直化(没懂什么意思)等)。
注意:如你在开发指南中的见的,建立REGION和item声明比 编程更可取。实际上,你应该只在不能用声明的方式来建立的时候才采用编程的方式,这样客户就能客户化你的页面了。
OAF—状态管理2

页面上下文
每次接收到一个页面的请求,OAF都建立一个OAPageContext存储信息,直到新的页面完成(特别的,OAPageBean建立OAPageContext,它主要是在页面后台起做作)
请求和页面边界
一个WEB应用的工作单元是一对请求/响应,浏览器发送请求,servlet处理这个请求并返回一个响应,响应的传送意味着一个请求的结束,或者是一个请求的完成与新的请求之前的分界。
同样,当OAPageBean完成页面的处理,这也是当前页面与新页面之间的分界。
所以,一个用户从页面X跳转到页面A,又跳转到页面B,这时我们有两个请求边界:X和A之间,A和B之间。也有两个页面边界:X和A,A和B。
 
有些情况下,请求和页面的边界不相同,考虑以下情况:
用户从X到A
在A的时候,在响应决定显示哪个页面之前,用户选择了A的控件,所以,浏览器发送了一个请求到A,当A处理结束,就达了第一个页的边界。
在页面A的代码中,开发者估算用户选择了哪个控件发送JSP FORWARD到页面B,因为我们不想重新显示A,所以不用反回HTTP响应,OAF开始处理页面B(包括建立一个新的OAPageContext),一旦B处理完成,就到达了第二个页面边界。
因为页面B必须显示给用户,故一个HTTP响应发送到浏览器,就到了请求的边界。
 
基于以下的原因,明白这一点是很重要的
l         请求参数存在于请求的生命周期中,它可以跨越多个页面的边界。这对于那些认为一个请求和一个页面相同的开发者来说有点奇怪,在JSP FORWARD后也不用说明请求参数还存在。如以下示例:
1.         用户选择了页面X中的连接,转到页面A,页面A的URL包括参数foo=bar
2.         页面A发送一个到页面B的JSP FORWARD,现在即使我们是在一个新的页面中,请求中仍然包括foo=bar
3.         如果你不想在jsp forward后还包括参数,你必须显式的覆盖它(注意你不能从请求中删除参数),如当你调用OAPageContext的setForward方法时你可以重置参数,foo=X
提示:将不需要的参数设为一个新值更可取,不要简单地将它设为“”。
l         因为在页面上下文与请之前没有一对一的关系,对于从OAPageContext中访问请求参数,有人会感到疑惑。只要记得每个页面是一个明确的实体,从它的“显示点”OAPageContext表示了一个请求。
l         当你进入上图的细节时,你会看到页面与请求的边界是明确的有不同含义的钝化事件点。
请求
尽管是生命周期很短,每个HTTP请求还是建立一个对象。这个对象包括以下应用状态:
所有的URL参数,不管是POST还是GET。
如果是POST请求,包括FORM中的数据。
如果是POST请求,web bean和事件名称会关联到用户选择的控件(如用户选择了一个GO按钮,请求会包括以这个按钮命名的web bean,所以你可以知道它被按下了并以此做出响应)。
为了访问请求值,使用OAPageContext的getParameter*()方法。
使用隐藏域
一个隐藏域是开发者在FORM中读取或写入数据工具,它不能被用户访问。如同用户看到的FORM域一样,隐藏域也在提交时被加到了请求中。
你可以通过在Jdeveoper中选择item style的formValue建立一个隐藏域。在运行时,它以oracle.apps.fnd.framework.webui.beans.form.OAFormValueBean来初始化。
在JSP FORWARD和重定向时指定值
当你显式的使用OAPageContext setForward*()或者OAPageContext.sendRedirct()方法转到一个新的页面时,你可以设定请求参数。
例如:假定有一个页面包括一个提交按钮,当用户点击时,我们想使用JSP FORWARD转到B页面。页面A需要一传递一个mode值给页面B(可以由不同的方式来访问),所以它知道如何做。
1、  用户点击提交按钮。
2、  在页面A的控制器中处理这个按钮,在processFormRequest方法中调用OAPageContext.setForwardURL()。做为一个方法调用,设定参数queryMode=automatic。
3、  在页面B的控制器中,在processRequest方法中检查参数queryMode值,调用getParameter(“queryMode”)。
4、  页面B控制器于是响应queryMode参数值为automatic,查询数据来显示页面。
调用OAPageContext.putParameter()指定值
OAPageContext包括putParameter()方法,在页面处理过程中,你可以用来传递值到web bean结构中,或者使用jsp forward从一个页面传到下一个页面。如:一个顶层的region可能放置一个值到缓存中,它的子region可以引用。
提示:这个和JAVA SERVLET 2.1的HttpServletRequest.setAttibute()方法很相似,可以认为它们做用相同。
设定URL参数
当在Jdeveloper中定义URL时你可以指定请求参数,或者在相关的程序中设置URL。
警告:URL是有长度限制的,你应该小心的添加URL参数的数量,尤其是很长的时候。因为URL是可见的,你应该加密敏感的值,然后再解密。
状态钝化模型(“Passivation”)
OAF是事务导向的,许多事务都跨越了多个页面。这些事务需要一定的状态来保存信息直到用户完成任务。如:一个建立采购定单的的流程中,用户在第一页描述定单,在第二页输入一个或多个项目,在第三页提交前检查信息,这个采购定单数据在每个浏览器提交的请求之间必须被保存。
HTTP协议是无状态的,它不能保存任何指定的状态也不保证支持状态保存。而且,如果提供servlet session的JVM实例失败了,或者servlet session超时了,应用状态就丢失了,等待的事务也不能恢复。
OAF,从另一方面来讲,当用户工作时,合并了保存与恢复客户端状态的能力,即使是servlet session超时(以后的版本会提供JVM失败的支持)。
l         保存应用状态到另一个地方(在OAF中,是保存在数据库中)叫做钝化。
l         从其它地方恢复应用状态叫做活化。
特别的,OAF目前提供了以下的状态管理特点:
可变的应用,当资源消耗很高时,OAF保存空闲线程的状态,并将它们的资源重新分配给其它线程,而不是新建一个资源实例。当空闲的线程激活时,保存的状态被恢复。简单说,资源会在JDBC连接、application modules、用户session中重新分配。
Servlet session 超时恢复,servlet session会超时,而不用用户重新开始一个未完成的事务(将来这个特点会扩展到提供中间层的失败支持)。
Application module 缓冲池
为了提高性能和可变性,OAF缓冲了APPLICATION MODULE,重用是比重建更有效的方式。在简单的情况下:
l         每个JVM都有一个application module池管理器,里面包含和管理不同的application module池。
l         每个application module池包含了一些application module的实例,如,如果一个应用使用了两个root application module,就有两个application module池:oracle.apps.fnd.framework.toolbox.tutorial.server.Lession3AM和oracle.apps.fnd.framework.toolbox.tutorial.server.Lession4AM,如下图。换句话说,每个root application module都建立一个池。
l         在池中的application module实例被设计成可用的或者不可用的(当前被提取走的)。
l         只有root application module是放在池中的,嵌套的application module是被root application module缓冲的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值