JSF教程(6)——生命周期中处理请求
来源:互联网 发布:java swing 日期控件 编辑:程序博客网 时间:2024/06/06 09:30
当JSF处理一个initial请求的时候程序将会创建一个新的view并且将它储存在FacesContext的实例中,这里需要注意的是只有在JSF的Response指向另一个JSF的View的时候上面的过程才会执行。其实这很好理解,如果简单一个超链接或者一个按钮将请求发送到服务器,而这个请求仅仅是跳转到一个不包含任何JSF组件的页面那么在服务端将没有任何View被产生,更别说被储存在FacesContext的实例中了。
关于FacesContext实例,在其中包含了处理request的和创建response的所有需要的信息。一般国内的翻译都会将“Context”翻译为“上下文”但是笔者更愿意将其理解为“一个保存了需要信息的环境”。在FacesContext实例中可以找到此次已经创建并存储的View以及和此次request以及Response有关的所有的信息。然后程序将调用用来渲染这个view的所有的资源,最后调用renderResponse方法立即渲染这个view(上篇博客图中的标有Render Response的箭头)。
可能有些情况下JSF需要重定向到其他的系统资源比如web service或者产生一个不包含任何JSF组件的response,在这种情况下开发人员必须调用responseComplete方法跳过Render Response这个步骤(步骤图中标有Response Complete步骤的箭头),道理很简单上面的两种情况都是不需要JSF去渲染页面的,所以响应就直接结束了。
读者可以参考JSF源码(jsf-impl-2.1.3,ViewHandlerImpl.java代码片段)
......public UIViewRoot restoreView(FacesContext context, String viewId) { if (context == null) { String message = MessageUtils.getExceptionMessageString (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "context"); throw new NullPointerException(message); } ExternalContext extContext = context.getExternalContext(); String mapping = Util.getFacesMapping(context); UIViewRoot viewRoot = null; if (mapping != null) { if (!Util.isPrefixMapped(mapping)) { viewId = convertViewId(context, viewId); } else { viewId = normalizeRequestURI(viewId, mapping); } } // maping could be null if a non-faces request triggered // this response. if (extContext.getRequestPathInfo() == null && mapping != null && Util.isPrefixMapped(mapping)) { // this was probably an initial request // send them off to the root of the web application try { context.responseComplete(); if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Response Complete for" + viewId); } extContext.redirect(extContext.getRequestContextPath()); } catch (IOException ioe) { throw new FacesException(ioe); } } else { // this is necessary to allow decorated impls. ViewHandler outerViewHandler = context.getApplication().getViewHandler(); String renderKitId = outerViewHandler.calculateRenderKitId(context); viewRoot = Util.getStateManager(context).restoreView(context, viewId, renderKitId); } return viewRoot; }......
上面的情况都不是我们平时常用的,仅仅是极少数的情况。在平时的开发过程当中我们遇到最常见的情况是从JSF页面跳转到另外的JSF页面。这时候就要经历图中主要的步骤(向下的箭头),转换,校验,模型更新,产生response。这与我们之前所了解的所有Web应用的处理步骤基本上是一致的。在这里需要读者注意的是在组件中有一个immediate属性,如果该组件的词属性设置为true那么JSF的生命周期将不按照正常情况进行下去。对于组件的immediate属性我们可以理解为:是否要求JSF对该组件立即(immediate)进行数据的校验(Validation)、更新值等操作,而不是在后面的步骤中进行操作,注意很多开发者认为immediate设置为true就是不进行数据的校验以及后面的一些列操作,这样理解是欠妥的。
接下来的博客将详细阐述JSF生命周期中的各个阶段的作用以及相关源码的分析。
- JSF教程(6)——生命周期中处理请求
- JSF教程(5)——生命周期概述(续)
- JSF教程(4)——生命周期概述
- JSF教程(7)——生命周期之Restore View Phase
- JSF教程(8)——生命周期之Apply Request Values Phase
- JSF教程(9)——生命周期之Process Validations Phase
- JSF教程(10)——生命周期之Update Model Values Phase
- JSF教程(11)——生命周期之Invoke Application Phase
- JSF教程(12)——生命周期之Render Response Phase
- JSF教程(3)——初探JSF中的Ajax
- JSF请求处理流程
- jsf in action 笔记:请求处理的生命周期(The Request Processing Lifecycle)--2008.04.08
- JSF请求处理过程详解
- JSF——事件处理
- JSF——表格处理
- JSF请求处理过程(一) FacesServlet初始化
- JSF请求处理过程(二)请求处理过程总览(FacesServlet#service)
- JSF教程(1)——简介 + HelloWorld
- POJ 2007 Scrambled Polygon
- 黑马程序员------第13天笔记(两个工具类)
- ADO.NET——Connection(连接数据库)
- NYOJ243交换输出
- URL编码与解码
- JSF教程(6)——生命周期中处理请求
- C++ socket传送整形数组(一)
- Strut2之Action配置中的各项默认值
- NYOJ 23 取石子
- JSF教程(7)——生命周期之Restore View Phase
- 无向图双连通分量uva1108
- Qt系列-5、控件的大小策略
- 【2Dhtml5游戏框架phaser介绍2】使用在线云IDE开发phaser
- 模块管理常规功能自定义系统的设计与实现(18--模块附件的设计[1])