背景介绍
在使用标准的 JSF Navigation 时需要为 指定确定的 URL 地址。如果为其配置 EL expression 会在运行时找不到页面,究其原因是因为没有对 EL 进行相应的赋值转化,即没有转化为 EL 所指定的 URL 地址。
项目中遇到如下问题:需要使
ADF Faces (不想对这个东西做更多的介绍,如果不是很清楚可以去
google 一把 )支持动态的导航,因为原有的好多导航链接都直接存放在了数据库中,而新系统必须依赖旧系统中的数据库(可以新添数据项,但不能删除已有的数据)。
实现原理
非常幸运地在网络上找到这篇文章
How to make JSF navigation rules more dynamic,其解决了基于 JSF 的解决方案,但是其针对的实现版本是 SUN 的官方实现。出于总结的目的,下文会把这篇文章的概要和实现在这里描述一下。
后来参读
JavaServer Faecs in Action (如想理解机制和原理,推荐这本书;如仅仅想快速进入开发,推荐
Core JavaServer Faces 2nd),发现原因主要集中在 ViewHandler 身上,因为在书中如此描述说明该类:
"The default Navigation-Handler instance selects a new view identifier based on the outcome and any configured navigation rules, uses the ViewHandler to create the new view, and sets it as the current view on the FacesContext. The selected view is then displayed by the ViewHandler during the Render Response phase of the Request Processing Lifecycle. The default ViewHandler handles this by forwarding the request to the web container, which processes the JSP page normally."
"The ViewHandler class is used internally by JSF to create new UIView-Root instances. This class is pluggable, so you can either decorate it or write an entirely new implementation—this is how JSF can support display technologies other than JSP."
现在明白了为什么 JSF 的 Navigation rules 中的 to-view-id 不支持 EL,原因是相应的 ViewHandler 不支持 EL expression 的解释。那么接下来的事情就简单了。
JSF (SUN version) - 这里的实现来自于上面的那篇文章,没有经过真正的测试
1. ViewHandler实现 - 继承 com.sun.facelets.FaceletViewHandler 并且 overwrite getActionURL().
java 代码
- @Override
- public String getActionURL(FacesContext context, String viewId)
- {
- String result = viewId;
- if(Util.isVBExpression(viewId))
- {
- ValueBinding vb = context.getApplication().createValueBinding(viewId);
- result = vb.getValue(context).toString();
- }
- result = super.getActionURL(context, value);
- int queryStart = value.indexOf("?");
- if((queryStart > 0) && (result.indexOf("?") == -1))
- {
- result = result + value.substring(queryStart);
- }
- return result;
- }
2. ViewHandler注册 - 注意体会 JSF 的 pluginable 机制的方便之处
xml 代码
- <application>
- ...
- <view-handler>com.interactive_objects.jsf.crud.generic.DynamicViewHandler<!---->view-handler>
- <!---->application>
3. Navigation配置
xml 代码
- <navigation-rule>
- <from-view-id>/pages/organisation/*<!---->from-view-id>
- <navigation-case>
- <from-action>#{OrganisationBean.select}<!---->from-action>
- <from-outcome>selected<!---->from-outcome>
- <to-view-id>#{OrgansiationBean.computedRedirect}<!---->to-view-id>
- <redirect/>
- <!---->navigation-case>
- <!---->navigation-rule>
ADF Faces 实现
ADF Faces 的实现和 JSF 的有所不同。在 SUN 的官方实现中,getActionURL 能够得到 to-view-id 的配置值,也就是说,无论你的配置值是什么,该方法都可以接受到。但是在 Oracle 的实现方法中,如果你的配置中包含有 EL expression,该方法是无法接受到配置值的,所以我们需要在 createView 方法中,实现上面的功能。
1. ViewHandler实现
java 代码
- package com.xxx.xxx;
-
- import oracle.adfinternal.view.faces.application.ViewHandlerImpl;
-
- import javax.faces.application.ViewHandler;
- import javax.faces.context.FacesContext;
- import javax.faces.el.ValueBinding;
- import javax.faces.component.UIViewRoot;
-
- import com.sun.faces.util.Util;
-
-
-
-
-
-
-
- public class CeViewHandler extends ViewHandlerImpl {
-
- public CeViewHandler(ViewHandler viewHandler) {
- super(viewHandler);
- }
-
- @Override
-
-
-
-
- public UIViewRoot createView(FacesContext facesContext, String s) {
-
- return super.createView(facesContext, parseExpression(facesContext, s));
- }
- @Override
- public String getActionURL(FacesContext facesContext, String s) {
- return super.getActionURL(facesContext, parseExpression(facesContext, s));
- }
- private String parseExpression(FacesContext facesContext, String s) {
- String result = s;
-
-
- if (Util.isVBExpression(s)) {
- ValueBinding vb = facesContext.getApplication().createValueBinding(s);
- result = vb.getValue(facesContext).toString();
- }
- return result;
- }
- }
接下来的步骤可以参考上面的 JSF 过程。
感觉 JSF 的 pluginable 机制还是有其某些方面的可取之处的,但是这个 server-state 的机制能够在走多远,我们只能拭目以待。(FYI: ADF Faces 可以实现 client-side state 了,绝不是广告,希望大家在用这个框架是三思,同时可以等
Apache Trinidad 发布正式版本后在去使用。)
分享到:
相关推荐
其中ADF Faces Rich Client是基于JavaServer Faces(JSF)技术的UI组件库,为开发者提供了丰富的用户界面组件来构建高度交互的应用程序。本篇文档旨在详细介绍如何使用ADF Faces Rich Client 11g进行基于Ajax的富...
ADF Faces提供了丰富的用户界面组件库,支持JavaServer Faces (JSF) 规范,为开发者提供了强大的交互式UI设计能力。ADF Faces组件不仅具有高度可定制性,还内置了AJAX支持,可以实现页面局部刷新,提升用户体验。 *...
ADF 的核心是基于 JSF(JavaServer Faces)技术,JSF 是一个用于构建用户界面的 Java 框架,它简化了创建动态、交互式的 Web 页面的过程。JSF 提供了一个模型-视图-控制器(MVC)架构,使得开发者可以专注于业务逻辑...
- Oracle ADF还提供了对JSF视图的增强,例如,通过ADF Faces提供的高级组件,可以更容易地实现动态数据展示和用户交互。 3. **Oracle ADF的关键特性**: - **组件库**:ADF Faces提供了大量的可重用UI组件,大大...
1、JavaServer Faces API(1.2) 2、JavaServer Faces Tag Library Documentation 3、ADF WebControls Java API 4、ADF Tag Library Documentation (chm格式)
JSF,即JavaServer Faces,作为Java平台的一个标准组件框架,其设计初衷是为了提供一种更为简化的方式来构建动态Web应用程序,特别是在表现层的处理上。尽管JSF在国内外的发展遭遇了一些挑战,比如面临Struts的竞争...
附件3 博文链接:https://hunte.iteye.com/blog/123559
首先,Oracle ADF是基于JSF(JavaServer Faces)的,这意味着它利用了JSF的UI组件和生命周期,提供了一种声明式的方式来创建用户界面。在MenuDemo中,我们可以看到ADF如何利用这些组件创建出动态、交互式的菜单系统...
JavaServer Faces(JSF)是Java平台上的一种用于构建用户界面的服务器端框架,它简化了Web应用程序的开发,尤其在处理表单提交、页面导航和组件管理等方面。本资源为《JavaServer Faces核心编程(第3版)》一书的源...
当我们谈论"ADF(JSF)框架中使用国际化"时,我们指的是如何使应用程序能够支持多种语言,以便全球用户都能方便地使用。 在ADF和JSF中实现国际化通常涉及到以下几个关键步骤和知识点: 1. **资源bundle**:国际化...
ADF Faces组件可以与JSF生命周期无缝集成,同时提供诸如AJAX支持、皮肤化、验证和转换等功能,使得开发者能够创建高度互动和用户体验良好的Web应用。 总之,JSF和ADF Faces提供了强大而灵活的工具,用于构建复杂的...
ADF Web界面开发指南还涵盖了ADFFaces组件的定制和扩展。开发者可以根据需要定制组件的外观和行为,以满足特定的业务需求。ADF框架提供了一套完整的API和工具,支持开发者创建自定义组件或对现有的组件进行扩展。 ...
ADF Faces 提供了一系列JSF(JavaServer Faces)组件,支持Web 2.0 功能,如AJAX更新、弹出窗口等。 4. **ADF Controller**:控制器处理用户输入,协调模型和视图间的交互。在ADF框架中,通常使用Task Flow和...
5. **ADF Mobile**:针对移动设备的应用开发,ADF提供了ADF Mobile框架,支持iOS和Android平台,使开发者能够创建跨平台的企业移动应用。 6. **adf.maf**:Mobile Application Framework (MAF) 是ADF的一部分,它是...
- **Oracle的ADFFaces**:这是一个完全符合JSF规范的组件库,为JSF应用程序开发提供了一组广泛的增强UI组件。 - **MyFaces**:这是一个开源项目,通过Apache提供,它对JSF的基本UI组件进行了增强,拥有更广泛的UI...