在这个过程其中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. Swift - 自定义函数规则说明

    1,无返回值的函数 1 2 3 func test(name:String){   } 2,返回一个返回值 1 2 3 func test(name:String) -> Bool{     r ...

  2. Delphi接口的底层实现(接口在内存中仍然有其布局,它依附在对象的内存空间中,有汇编解释)——接口的内存结构图,简单清楚,深刻 good

    引言 接口是面向对象程序语言中一个很重要的元素,它被描述为一组服务的集合,对于客户端来说,我们关心的只是提供的服务,而不必关心服务是如何实现的:对于服务端的类来说,如果它想实现某种服务,实现与该服务相 ...

  3. 奔小康赚大钱 hdu 2255

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  4. 并发编程实践五:ReentrantLock

    ReentrantLock是一个可重入的相互排斥锁,实现了接口Lock,和synchronized相比,它们提供了同样的功能.但ReentrantLock使用更灵活.功能更强大,也更复杂.这篇文章将为 ...

  5. hdu1171(DP求两份物品的价值相差最小)

    题目信息: 给出一些物品的价值和个数.分成两份,是这两份的价值相差最小(DP方法) http://acm.hdu.edu.cn/showproblem.php? pid=1171 AC代码: /** ...

  6. Git使用之搭建基于SSH的Gitserver(上篇)

    1. 须要软件 msysgit (Gitfor Windows) Copssh (OpenSSHfor Windows,新版本号已经開始收费了大家能够去搜索引擎找曾经的免费版Copssh_4.1.0下 ...

  7. loj1245(数学)

    传送门:Harmonic Number (II) 题意:求sum=n/1+n/2+n/3+...+n/n.(n<2^31) 分析:在一定的区间内n/i的值是一定的,因此要跳过这段区间来加速求解. ...

  8. hdu2844(多重背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844 题意:一位同学想要买手表,他有n种硬币,每种硬币已知有num[i]个.已知手表的价钱最多m元,问 ...

  9. HTML5: Screen Orientation API

    媒体的询问取决于智能手机和平板布局调整的方向一致网站.但有时候你被锁定在一个希腊网站特定方向.横向或纵向.此时,是本机格式可以指定保健应用. APP只显示在一个预设格式-独立于实际设备方向.通过使用H ...

  10. 开源一个适用iOS的数据库表结构更新机制的代码

    将前段时间开源的代码.公布一下: ARDBConfig On the iOS, provide a database table structure update mechanism, ensure ...