在这个过程其中JSF的实现者使用processValidators方法处理全部在tree中的组件中注冊的验证器。验证的过程就是通过每一个组件已有的规则对其已经保存的值进行校验,同一时候也对输入的值进行校验,前提是组件的immediate属性没有设置为true。从代码来看在UIViewRoot中的这个processValidators方法和上个阶段中的processDecodes基本一致。不用说下一个阶段(Update ModelValues Phase)也会有相相似的方法(processUpdates)。之所以JSF会这样设计是由于这三个阶段(取值、校验、更新)所作的事情对于每一个组件(一个View的各个部分)而言是一致的。

PartialViewContextImpl中经典的一个方法。此方法将“处理”抽象了出来,妙不可言哇。

public void processPartial(PhaseId phaseId) {
updateFacesContext();
PartialViewContext pvc = ctx.getPartialViewContext();
Collection <String> executeIds = pvc.getExecuteIds();
Collection <String> renderIds = pvc.getRenderIds();
UIViewRoot viewRoot = ctx.getViewRoot(); if (phaseId == PhaseId.APPLY_REQUEST_VALUES ||
phaseId == PhaseId.PROCESS_VALIDATIONS ||
phaseId == PhaseId.UPDATE_MODEL_VALUES) { // Skip this processing if "none" is specified in the render list,
// or there were no execute phase client ids. if (executeIds == null || executeIds.isEmpty()) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE,
"No execute and render identifiers specified. Skipping component processing.");
}
return;
} try {
processComponents(viewRoot, phaseId, executeIds, ctx);
} catch (Exception e) {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO,
e.toString(),
e);
}
} // If we have just finished APPLY_REQUEST_VALUES phase, install the
// partial response writer. We want to make sure that any content
// or errors generated in the other phases are written using the
// partial response writer.
//
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
PartialResponseWriter writer = pvc.getPartialResponseWriter();
ctx.setResponseWriter(writer);
} } else if (phaseId == PhaseId.RENDER_RESPONSE) { try {
//
// We re-enable response writing.
//
PartialResponseWriter writer = pvc.getPartialResponseWriter();
ResponseWriter orig = ctx.getResponseWriter();
ctx.getAttributes().put(ORIGINAL_WRITER, orig);
ctx.setResponseWriter(writer); ExternalContext exContext = ctx.getExternalContext();
exContext.setResponseContentType("text/xml");
exContext.addResponseHeader("Cache-Control", "no-cache");
writer.startDocument();
if (isRenderAll()) {
renderAll(ctx, viewRoot);
renderState(ctx);
writer.endDocument();
return;
} // Skip this processing if "none" is specified in the render list,
// or there were no render phase client ids.
if (renderIds == null || renderIds.isEmpty()) {
} else {
processComponents(viewRoot, phaseId, renderIds, ctx);
} renderState(ctx); writer.endDocument();
} catch (IOException ex) {
this.cleanupAfterView();
} catch (RuntimeException ex) {
this.cleanupAfterView();
// Throw the exception
throw ex;
}
}
}

假设本地值不合法。或者不论什么转换失败那么JSF的实现将会在FacesContext实例中添加一条错误信息。然后生命周期直接跳转到Render Response阶段页面会被再次渲染并且附带上刚才的错误信息。当然之前产生的放在FacesContext中的错误信息也会一并显示出来。

假设在当前FacesContext实例中不论什么validate方法或者事件监听器调用renderResponse方法JSF实现将跳到Render Response阶段。

和上个阶段一样假设程序须要重定向到不同web应用资源或者生成一个不包括JSF组件的响应那么会调用FacesContext.responseComplete方法。

假设当前请求被定义为一个局部的请求,那么局部内容会被从FacesContext中回复,并且局部处理方法会被运行。

细心的读者可能看出来了后面的三种情况和上一步骤中的流程是惊人的相似。这归根结底是由于JSF实现者人为的将Execute步骤分成了6个不同的阶段,可是这六个阶段中的中间三个( Apply Request Values Phase、Process Validations Phase、Update Model Values Phase)阶段从本质上来看是一模一样的。这三个阶段都是为组件中值的展示服务的,不论是取值,还是校验,还是更新他们都是同样得逻辑不同的细节,这也就能解释了为什么三个阶段能够公用上面贴出的一套代码而只用传入不同的PhaseId。

哦,策略模式!

好像又不太像。这里不过传递不同的參数然后不同的操作而已。工厂?有些相似,可是不全然是,工厂最起码得有创建吧。想了一圈设计模式也不知道哪个能和这里的实现相相应,总之这里抽象了,复用性高了。耦合性恰到优点。

JSF教程(9)——生命周期之Process Validations Phase的更多相关文章

  1. JSF教程(11)——生命周期之Invoke Application Phase

    在这个阶段JSF实现将处理不论什么应用界别的事件,比如表单的提交或者链接点击后跳转到还有一个页面. 这时假设应用须要重定向不同 的web应用字眼或者产生一个资源其并不喊不论什么的JSF组件,那么就调用 ...

  2. 前端组件化Polymer入门教程(5)——生命周期

    以前我对生命周期这个概念还真不是很清楚,不过想想也简单,比如说人的生命周期,无非就是生老病死.而对于程序的生命周期就是说,它在每个阶段都会做不同的事,再比如说回调函数把,ajax返回的时候它才执行,那 ...

  3. Android Studio教程03-Activtiy生命周期的理解

    目录 1. Activity 1.1. 安卓中的Activity定义和特性: 1.2. 注册Activity 1. Intent filters:设置默认开启的activity 1.3. Activi ...

  4. JSF控件的immediate属性和页面生命周期

    JSF中的控件基本都有immediate属性,对于这个属性的使用总结如下,更详细内容可参考Oracle官方文档. 1,为了更好的理解immediate属性,先看一下JSF页面的生命周期: JSF页面的 ...

  5. JSF生命周期&Facelets的生命周期

    1.JSF生命周期 1)恢复视图(Restore View) 视图表示组成特定页面的所有组件.它被保存在 客户端(通常存储在隐藏字段中)或服务器中(通常在会话中).根据请求访问的视图ID(页面地址), ...

  6. Maven使用教程三:maven的生命周期及插件机制详解

    前言 今天这个算是学习Maven的一个收尾文章,里面内容不局限于标题中提到的,后面还加上了公司实际使用的根据profile配置项目环境以及公司现在用的archetype 模板等例子. 后面还会总结一个 ...

  7. Maven 的插件和生命周期的绑定

    一.Maven 的生命周期 Maven 的生命周期是对所有的构建过程进行抽象和统一.Maven 的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,生命周期只是定义了一系列的阶段,并确定这些阶 ...

  8. 《Maven实战》 第7章 生命周期与插件

    7.1什么是生命周期 软件开发人员每天都在对项目进行清理.编译.测试及部署,Maven生命周期是对所有构建过程进行抽象和统一,含项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几 ...

  9. Maven入门指南⑦:Maven的生命周期和插件

    一个完整的项目构建过程通常包括清理.编译.测试.打包.集成测试.验证.部署等步骤,Maven从中抽取了一套完善的.易扩展的生命周期.Maven的生命周期是抽象的,其中的具体任务都交由插件来完成.Mav ...

随机推荐

  1. java32至md5加密

    码,如以下 <span style="font-size:18px;">import java.security.MessageDigest; import java. ...

  2. android之写文件到sd卡

    1.main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...

  3. SQLite/嵌入式数据库

    SQLite/嵌入式数据库 的项目要么不使用数据库(一两个文配置文件就可以搞定),要么就会有很多的数据,用到 postgresql,操练sqlite的还没有.现在我有个自己的小测试例子,写个数据库对比 ...

  4. 《转》在win7,boa-constructor 0.6.1 的palette面板中没有控件图标的解决方法

    原地址:http://blog.csdn.net/rickleo/article/details/6532595 在win7-64bit环境下,boa-constructor 0.6.1 的palet ...

  5. [Android学习笔记]使用ListView

    简单使用ListView 关键在于Adatper Adatper用来连接UI与数据源.Adapter既负责提供数据,又负责创建Item视图. 一般步骤: 1.创建list_item.xml,用来创建L ...

  6. iOS学习——JSON数据解析(十一)

    在之前的<iOS学习——xml数据解析(九)>介绍了xml数据解析,这一篇简单介绍一下Json数据解析.JSON 即 JavaScript Object Natation,它是一种轻量级的 ...

  7. [LeetCode]Swap Nodes in Pairs 成对交换

    Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2-& ...

  8. [品质生活] 舒适 Schick HYDRO 5剃须刀

    [品质生活] 舒适 Schick HYDRO 5剃须刀 [品质生活] 舒适 Schick HYDRO 5剃须刀

  9. 实现ListView A~Z快速索引

    ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法. 实现步骤: 1.自定义一个名叫SlideBar 的View. 2.在布局文件中加入这个 ...

  10. 使用MYCAT作为Mysql HA的中间件(转)

    记得在上一篇文章“Java集群--大型网站是怎样解决多用户高并发访问的”的结尾处本人阐述了数据库的高可用的一种方案----实现主从部署,那么今天,就让我聊聊本人关于数据库的一些所思所想吧! 下面是本人 ...