BlogJava

研究、学习Java的地方

  DonewsBlog  |  Donews首页  |  Donews社区  |  Donews邮箱  |  我的首页  |  联系作者  |  聚合   |  登录
  161篇文章 :: 3篇收藏:: 87篇评论:: 0个Trackbacks

公告



Locations of visitors to this page

文章

收藏

相册

Java

软件工程

数据库

新闻

存档


正在读取评论……


JSF指南

记录自己学习jsf的过程,与你分享学习的快乐

    摘要:在这个状态,所有的过程都已经被框架和应用程序处理完毕。装饰请求状态的目的就是把所有的返回结果显示给用户,这也是它主要完成的功能。这个状态的另一个功能是保存视图的状态,这样就可以在重现视图状态中 在用户需要的时候将页面重现显示。通常的应用中视图的状态是保存在客户端的,那么为了达到重现视图的目的在JSF中视图的状态是保存在服务器端的,大多数 情况下视图状态被保存在用户的会话(session)中。记住,JSF不是一个专门用来进行页面显示的技术,因此我们还有其他几种方式来显示返回的结果:
  •   只使用视图中提供的控制方法输出结果
  •   结合视图中的控制方法和应用程序代码输出结果
  •   使用静态模版资源输出结果
  •   使用动态方法输出结果,就像JSP那样。
所有JSF的实    (全文共950字)——点击此处阅读全文


    摘要:在这个状态,所有的支持Bean和模型对象的数据都已经被更新了,现在可以执行业务逻辑了。    (全文共2613字)——点击此处阅读全文


    摘要:现在所有组件的值已经正确的更新,并且通过了验证,接下来我们将把组件值和支持Bean以及模型对象进行关联。因为组件和对象是通过JSF EL标记管理的,因此支持Bean和模型对象属性值的更新依赖于页面组件的实际值。让我们再来看看上面例子中HtmlInputText中这部分是如何声 明的:
        <h:inputText id="helloInput" value="#{helloBean.numControls}"
        required="true">
        ...
        </h:inputText&    (全文共918字)——点击此处阅读全文


    摘要:在处理校验的状态下,JSF会遍历组件树,确保提交的值是有效的。因为在“接收请求值”状态每个组件的值已经被更新了,所以组件当前的值是来自用户提交的最新数据。在校验之前可能发生这样的情况,被校验的值已经由组件的转换器转换过了。这时,校验器可能由组件直接控制或者分派更多的校验器。    (全文共1552字)——点击此处阅读全文


    摘要:所有的组件值都是通过用户提交获得的。在接收请求值的状态中,JSF框架通过请求传输的参数来设置提交值。这一过程称为“编码”    (全文共1973字)——点击此处阅读全文


       一个视图代表了一个页面包含的所有组件。它可以存放在客户端(通常是在浏览器的隐藏字段中)也可以存放在服务器端(通常是在服务器会话中)。在上面的例中 它存储在会话中,这样是默认使用的方式。一个视图由一系列组件组成并且有一个唯一的ID。这个ID与页面请求路径相同(这是JSF缺省的实现方式,其他的 实现方式有所不同;比如Smile开源项目的实现是:视图标记ID可以通过一个创建组件树的Java类来产生)。所以如列表2.1总所示(/jia- hello-world/faces/hello.jsp),这个视图的ID就是servlet后面的hello.jsp。
       因为这里的请求是由用户点击hello.jsp页面上的一个按钮发出的,所以这个页面发出的请求和它收到的请求其实是一样的。页面的执行过程是把“请求” 发回给“自身”。如果你熟悉Struts,那么它和Struts给Action类映射一个URL不同,在JSF框架中返回的URL被存放在一个“事件列 表”中,然后框架会“执行一个事件”。
       JSF事件提供了更多更加有条例的事件,比如“用户执行了一个命令”或者“用户改变了这个组件的值”。JSF事件中需要关注的是请求是从哪一个页面发出 的。当JSF从一个页面接收到请求时,它需要判断请求是从哪个页面发出的,以此分辨用户触发的事件,从而关联到页面上触发事件的具体组件。
       这就是还原视图状态完成的主要工作-查找用户视图并接收用户在视图中的输入。因此,它会在用户会话中查找视图。如果视图不存在,就丢弃这个视图,并更加请 求ID创建一个新的视图。一旦视图被找到或者创建就会存储在当前的FacesContext中。下面上我们看看前面降到的hello.jsp应用程序中组 件树的组成结构,如图2.5

图2.5

        如你所见,整个页面包含了一套简单的组件树。首先是UIViewRoot组件,它是一个容器组件,所有其他组件都要放在它的上面。UIViewRoot有 一个子组件是HtmlForm组件它的ID是welcomeForm。HtmlForm有多个子组件,包括一个HtmlInputText组件他的ID是 helloInput,以及两个HtmlCommandButton组件分别名为“redisplayCommand”和 “goodbyeCommand”。另外还有HtmlOutputLabel和HtmlOutputText组件。
       还原的视图中确保每个组件都有正确的值,以及事件监听器、校验器和相关的转换器。在这个例子中HtmlInputText组件有一个LongRange校 验器。另外,redisplayCommand组件有一个action属性,goodbyeCommand有一个actionListener。
      如果任何组件绑定了支持Bean中的属性,Bean的属性和组件会在这个状态进行同步。在这个例子中helloBean的controlPanel属性会 与名为controlPanel的HtmlPanelGrid组件同步。这样就可以在支持Bean的监听器方法中对组件进行控制。
       另外,还可以在这个状态设置视图使用的语言。如果请求是调用“自身”的,JSF将继续执行下一个状态,否则,如果是一个初始化请求(之前用户已经请求过这个页面),JSF将直接跳转到“返回响应”状态,因为用户没有进行任何输入操作。

           设计一个包含有序选择的冗长列表需要非常复杂的设计模式。这种模式需要将可选项显示在一个列表中,同时还需要在另一个地方进行选择,所以需要用户的可以方便的进行选择和修改.
这种模式通常称为双重列表或者叫双重列表框选择器.它又被称为选择概要或者列表创建者模式.按照Java Look and Feel的设计规则,它又被称为增加-移除模式。
标准的Struts实现,需要试用JSP,Java和JavaScript。JavaServerFace不需要JSP技术,但是比起Struts要简单的多。
列表1是使用Struts技术的JSP代码,列表2是使用JavaServerFace技术的JSP代码。JSF的支持Bean,配置文件和其他文件的代码可以从JDJ网站下载。
Jakarta Struts的实现方式
使用Jakarta Struts技术,JSP需要定义一个表格来显示树状列。在第一列和第三列,可选列通过<html:select>标签和<html: optionCollection>来实现。为了实现国际化要求,label标签使用了JSP标准表情库中的<fmt: message>标签。很多人发现结合Struts和JSTL标签一切使用功能非常强大。
<table border="0" cellpadding="0" cellspacing="5">
<tr align="middle" valign="center">
<td>
<fmt:message key="titles.available"/><br />
<html:select property="availableValues"
multiple="true" size="7"
style="width:80px;" styleId="available"
onchange="doUpdate( false, true );">
<html:optionsCollection
property="availableList"/>
</html:select>
</td>
...
<td>
<fmt:message key="titles.chosen"/><br />
<html:select property="chosenValues"
multiple="true" size="7"
style="width:80px;" styleId="chosen"
onchange="doUpdate( true, false );">
<html:optionsCollection
property="chosenList"/>
</html:select> </td>
</tr>
</table>
Struts的表单Bean包含了用于JSP的“可见列表”,“可见值”,“可选列表”和“可选值”属性。
private List availableList = new ArrayList();
private String[] availableValues = new String[ 0 ];
private List chosenList = new ArrayList();
private String[] chosenValues = new String[ 0 ];
...
public List getAvailableList()
public void setAvailableList( List list )
public String[] getAvailableValues()
public void setAvailableValues( String[] list )
public List getChosenList()
public void setChosenList( List list )
public String[] getChosenValues()
public void setChosenValues( String[] list )
“availableList ”和“chosenList ”属性通过标签值Bean的方式封装了列表的可见值。“availableValues ”和“chosenValues ”以字符串数组的形式存储了可选的值。
对于增加-选择模式来说,不会关心这些可选值。对于服务器来说我们只要告诉它列表中显示什么值而无需告诉它那个值被选中了。然而当表单被提交后,只有被选中的值会被提交给服务器。这是通常使用的设计方法,但是这种设计模式存在问题。如图1.
下 面有集中方法可以解决这个问题。一种方法是在每次列表内容发生变化的时候都向服务器提交一次值。者引发了过度的页面引用和网络负载。另一种方法是使用 AJAX技术与服务器进行通信。这减少了页面的刷新,但是仍然会代理网络的负载。直到用户完成列表变更之前都不应该产生网络负载。
最好的解决方案是把选中的值存储在一个隐藏字段中。使用这种方法当表单提交时只向服务器提交一次值。在这个例子中我们把选中的值存储在一个隐藏字段中。利用这个隐藏字段,两个列表中见的按钮可以这样实现:

<td>
<br />
<input type="button" style="width:100px;" id="add" onclick="
doMove( 'available', 'chosen', false );" value="<fmt:message key='add'/>" /><br />
<input type="button" style="width:100px;" id="addAll" onclick=
"doMove( 'available', 'chosen', true );" value="<fmt:message key='addAll'/>" /><br />
<br />
<input type="button" style="width:100px;" id="remove" onclick=
"doMove( 'chosen', 'available', false );" value="<fmt:message key='remove'/>" /><br />
<input type="button" style="width:100px;" id="removeAll" onclick=
"doMove( 'chosen', 'available', true );" value="<fmt:message key='removeAll'/>" />
<html:hidden styleId="chosenItem" property="chosenItem" />
</td>
这个按钮通过HTML标签<input>实现。<html:hidden>字段存储了选中的值。被选中的值通过JavaScript方法“doMove()”进行保存,所有4个按钮都执行这个方法。

/**
* Move selected items between lists.
* <p>
* @param sourceId ID of source list
* @param destId ID of destination list
* @param all true iff moving all
*/
function doMove( sourceId, destId, all )
{
// Move the items between the lists.
var sourceElem = document.getElementById( sourceId );
var destElem = document.getElementById( destId );
for( var i = 0; ( i < sourceElem.length ); )
{ if( sourceElem.options[ i ].selected || all )
{ var newOption = document.createElement( "OPTION" );
newOption.text = sourceElem.options[ i ].text;
newOption.value = sourceElem.options[ i ].value;
destElem.options[ destElem.length ] = newOption;
sourceElem.remove( i );
}
else
i++;
}
// Update the button states.
doUpdate( false, false );
// Store the chosen items in a hidden field.
var chosenItem = document.getElementById( "chosenItem" );
var chosenList = document.getElementById( "chosen" );
chosenItem.value = "";
for( var i = 0; ( i < chosenList.length ); i++ )
{ chosenItem.value += chosenList.options[ i ].value + '|';
}
}
上面的方法非常易于理解,使用起来也很方便。按钮只要在需要的时候才会显示。比如如果没有列表值被选中,那么“Add”和“Remove”按钮就无法使用。当显示列表和选择列表都是空的时候,那么“Add All”和“Remove All”按钮就无法使用。
“doUPdate()”函数根据用户的选择和列表中包含的内容判断按钮是否可以显示。如图2
“doUpdate()”方法由上面由列表控件的OnChange方法触发的“doMove()”方法调用。或者在body的onload方法中调用。

/**
* Update the button states based on whether
* lists have contents and selected items.
* Deselect list items if requested to ensure
* at most one list contains selections.
* <p>
* @param offAvailable deselect available list
* @param offChosen deselect chosen list
*/
function doUpdate( offAvailable, offChosen )
{
// Get the lists and deselect if requested.
var availableList = document.getElementById( "available" );
var chosenList = document.getElementById( "chosen" );
if( offAvailable ) availableList.selectedIndex = -1;
if( offChosen ) chosenList.selectedIndex = -1;
// Update the button states.
document.getElementById( "addAll" ).disabled =
( availableList.length == 0 );
document.getElementById( "removeAll" ).disabled =
( chosenList.length == 0 );
document.getElementById( "add" ).disabled =
( availableList.selectedIndex < 0 );
document.getElementById( "remove" ).disabled =
( chosenList.selectedIndex < 0 );
}
使用JavaScript函数,列表中包含的内容被正确的更新,用户选择的值被保存在一个隐藏字段中。在这个例子中它被用于控制两个列表中值和用户的选择。
列表中的值被存储在表单Bean中的一个“languageList”属性里。这个列表中包含了所有可能的选项。move方法利用“chosenItem”列表中的值控制了“可见”和“可选”列表中的值。

private List languageList = new ArrayList();
private String chosenItem = "";
...
public List getLanguageList()
public void setLanguageList( List list )
public String getChosenItem()
public void setChosenItem( String items )
public void move( List sourceList, String[] sourceValues, List destList )
...
"languageList" ,"chosenItem" 属性和 "move"方法通过表单提交的Action中的“execute”方法执行。在Struts中是StrutsAction类的实例。

/**
* Populate the lists from the hidden field.
* <p>
* @param mapping action mapping
* @param form action form
* @param request HTTP servlet request
* @param response HTTP servlet reponse
* @throws Exception
*/
public ActionForward execute( ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response ) throws Exception
{
// Populate available list from language list.
ExampleForm eForm = ( ExampleForm )form;
eForm.getAvailableList().clear();
eForm.getAvailableList().addAll( eForm.getLanguageList());
// Populate chosen list from hidden field.
eForm.getChosenList().clear();
eForm.move( eForm.getAvailableList(),
eForm.getChosenItem().split( "\\|" ),
eForm.getChosenList());
}
JavaServerFace实现
那么JavaServerFace中是如何实现上面的模式呢?JSF由一群曾经设计过Struts的人设计,所以我们可以较容易的从Struts过度到JSF。
JSF 中的JSP也包含了两个列表,因为JSF的标签更加紧密。代替<table>,<tr>和<td>标签,JSF使用 了<h:panelGrid>标签。代替Struts中的<fmt:message>标签JSF使用了<h: outputText>。代替<html:select>和<html:optionsCollection>标签, JSF使用了<h:selectManyListBox>和<f:selectItems>。

<h:panelGrid columns="3" rowClasses="center">
<h:outputText value="#{bundle.available}" />
<h:outputText value="" />
<h:outputText value="#{bundle.chosen}" />
<h:selectManyListbox style="width:100px; height:120px;"
id="available" value="#{example.availableValues}"
onchange="doUpdate( false, true );">
<f:selectItems value="#{example.availableList}"/>
</h:selectManyListbox>
...
<h:selectManyListbox style="width:100px; height:120px;"
id="chosen" value="#{example.chosenValues}"
onchange="doUpdate( true, false );">
<f:selectItems value="#{example.chosenList}"/>
</h:selectManyListbox>
</h:panelGrid>
就 像Struts中实现的那样,<h:selectManyListBox>标签映射了支持Bean中的“availableList” “availableValues”和“chosenList”以及“chosenValues”属性,他们等同于Struts中的相应属性。
就像Struts实现中的一样,四个按钮也由标准HTML的<input>标签实现。
在JSF中这些标签还必须附上<f:verbatim>标签。除此之外这些标签和Struts中的没什么不同。这里有一点与Struts类似的就是在每个JavaScript方法中经常需要包含一个“form:”前缀。

<h:panelGrid columns="1">
<f:verbatim>
<input type="button" style="width:100px;"
id="add" onclick="doMove( 'form:available', 'form:chosen', false );"
value="<fmt:message key='add'/>" /><br />
<input type="button" style="width:100px;"
id="addAll" onclick="doMove( 'form:available', 'form:chosen', true );"
value="<fmt:message key='addAll'/>" /><br />
<br />
<input type="button" style="width:100px;"
id="remove" onclick="doMove( 'form:chosen', 'form:available', false );"
value="<fmt:message key='remove'/>" /><br />
<input type="button" style="width:100px;"
id="removeAll" onclick="doMove( 'form:chosen', 'form:available', true );"
value="<fmt:message key='removeAll'/>" />
</f:verbatim>
<h:inputHidden id="chosenItem" value="#{example.chosenItem}" />
</h:panelGrid>
除此之外,JSF中的doMove方法和doUpdate方法没什么不同。
JSF的优势是它控制了提交事件。在JSF中你可以明确的定义一个按钮具体执行那个请求。
<h:commandButton action="#{example.submit}" value="#{bundle.submit}" />
“example:submit”方法会读取隐藏字段中内容并更新列表。因为这个方法直接关联在一个提交按钮上,所以你不必单独实现一个Action对象。
public String submit()
{
// Populate the available list from the language list.
availableList.clear();
availableList.addAll( languageList );
// Populate the chosen list from the hidden field.
chosenList.clear();
move( availableList, chosenItem.split( "\\|" ), chosenList );
...
return( "success" );
}
JSF中不需在学什么,虽然标签不同,但是通常和JSP中的类似。Java代码也差不多。
需 要强调的是JSF中的组件架构。如果你下载了免费的SUN Java Studio Creator,你会发现它包含了一整套可以在你的GUI中任意增加-删除的组件。SUN的组件包含很多功能,比如“Move Up”和“Move Down ”按钮可以改变列表中值的顺序。我们还可以列举很多这样的有用组件。
结论

这篇文章展示了一个从两个列表中取值的标准UI设计模式。通过Jakarta Struts和JavaServer Face两种方式实现。
JSF提供了一种从Struts平滑过度的方法。JSP的标签非常简单那;支持Bean的代码也和Struts类似;并且,如果你需要使用JavaScript在JSF中的用法也是一样的。
你可以把JSF当成是一个简单的,组件化的Struts。它增加了很多有用的特性,并且减少了复杂性。
对于大多数刚接触Web项目的开发人员,JavaServer Faces是一个很好的选择。对于熟悉Struts的开发人员,过度到JSF也很容易。


之前我们讲述的概念中所有操作都是在一个单独的页面上。在实际的Web应用开发中,这是不太可能的。Web应用的开发会有很多页面,我们必须提供一种方法实现不同页面之间的切换。实现从一个页面到另一个页面切换的机制被称为“导航”。

JSF中有一套非常完善的导航系统。导航控制器根据请求实现的返回值确定下一个页面跳转到哪里。对于给定的页面,一个导航规则定义了根据业务逻辑的动作事件判断页面应该如何跳转。根据导航规则发生的每一个页面跳转被称为一个导航事件。导航规则定义在JSF的配置文件中。下面这个例子演示了针对longin.jsp页面的两个导航事件:success和failure的一个导航规则。


<navigation-rule>
     <from-view-id>/login.jsp</from-view-id>
     <navigation-case>
     <from-outcome>success</from-outcome>
     <to-view-id>/mainmenu.jsp</to-view-id>
     </navigation-case>
    <navigation-case>
    <from-outcome>failure</from-outcome>
    <to-view-id>/login.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

如 你所见,每一个出口对应一个JSP页面,这里你不需要通过编码实现这些规则。如果你曾经使用过Struts你对这种定义方式一定不会陌生。你会发现,所有 的导航事件只映射一个出口(对应一个jsp),也就是说,如果将来需要进行变更你只需要修改需要变更的那一个页面就可以了而不是修改多处。

现在,JSF中的几个基本概念已经介绍完了。在随后的讲解中我们会看到更多的例子。已经这些概念集中到一起是如何使用的。


前面我们讲了JSF中包含的:组件、事件、监听器以及很多好用的组件,这些功能都使得JSF的开发变得更简单。那么这些部分的执行过程是什么样的呢?为了更容易理解,我们讲分析JSF框架的底层Servlet API,这对于你更好的理解JSF的执行过程是有好处的。了解了这些内容也有助于你开发出更好的应用程序,因为你明白底层到底是如何运行的。当然如果你是一个WEB界面开发人员,你完全可以跳过这个部分。
    在这一节中我们讲讨论JSF是如何对请求作出响应的。或者说,由包含JSF组件的页面发出的请求是如何被JSF处理的。
    图2.4是一个状态图,它显示了当接收到来自客户端发出的请求后JSF是如何处理的,即JSF的请求处理过程。这个过程开始于JSFservlet接收到一个来自客户端的请求(记住JSF是建立在Servlet基础之上的)
          

   图2.4
        列表2.2对以上每一个状态进行了注释,其中主要有六个状态,每一个状态之后多会有相应的时间产生。JSF将这些事件交给相应的监听器进行处理,不管监听 器是处理某些业务逻辑还是组件,都能够继续跳转到最终的状态,显示响应结果。监视器也可以跳过最终的状态直接显示一个响应结果,比如它可以返回一个二进制 内容,执行一个页面跳转或者返回其他与JSF有关的内容比如XML文档或者是一个HTML。
        以上六个步骤中有四个可以产生消息,它们分别是:接收请求值(Apply Request Values),执行验证(Process Validations),更新模型值(Update Model Vlaues),和提交应用程序(Invoke Application)。不管是否带有消息,这些状态都能够向用户反馈响应,除非监听器、装饰器或者组件自身直接返回响应。这些状态之后是一个依据时间 主线提交应用程序的过程。一系列的组件、校验过程、支持Bean和模型对象将被更新。简单的讲,JSF为你完成了大部分工作:它捕获了请求的详细信息并把 它们传输给包含组件和时间的高层视图,而且还更新了相关对象的属性。
表2.2 JSF 各个状态的请求响应过程
状态
描述
触发的事件
还原页面(Restore View)
为选择的页面查找或创建一个组件树。一些组件,比如HtmlCommandButton组件在此状态下将产生动作事件(或者其他事件)
状态事件
接收请求值(Apply Request Values)
比较请求传输的值并更新相应组件的值,也可以使用转换器。如果出现异常将抛出一个异常消息。同时会产生来自请求参数的事件。
状态事件
数据模型事件
动作事件
处理验证(Process Validations)
对每个组件执行验证。可能会产生验证消息。
状态事件
数据模型事件
值变化事件
更新模型值(Update Model Values)
更新与组件相关的所有模型对象和支持Bean的值。可能会产生异常消息。
状态事件
数据模型事件
提交应用程序(Invoke Application)
调用注册的监听器。缺省的监听器将执行命令组件(比如HtmlCommandButton)的事件方法或者选择下一个要显示的视图。
状态事件
动作事件
返回相应(Render Response)
显示当前逻辑指定的下一个响应页面。
状态事件

       为了让你对此有一个更清晰的了解。我们将通过一个hello world的例子展示JSF处理请求过程的整个生命周期。这个例子来自于我们前面章节讲述的hello.jsp。列表2.1显示了实际上Http的处理过程。
列表2.1 Http 的请求过程
POST /jia-hello-world/faces/hello.jsp HTTP/2.1                 (1)接收来自URL的请求
Host: deadlock:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:2.2.1)
Gecko/20021130
Accept: text/xml,application/xml,application/xhtml+xml,text/html;
q=0.9,text/plain;q=0.8,video/x-mng,image/png,
image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Language: en-us, en;q=0.50
Accept-Encoding: gzip, deflate, compress;q=0.9
Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive
Referer: http://deadlock:8080/jia-hello-world/faces/hello.jsp  (2)同样是接收来自URL的请求
Cookie: JSESSIONID=58324750039276F39E61932ABDE319DF  (3)会话标记
Content-Type: application/x-www-form-urlencoded
Content-Length: 92
welcomeForm%3AhelloInput=64&                              (4)组件值
welcomeForm%3AredisplayCommand=Redisplay&
welcomeForm=welcomeForm
        我们并不打算讨论Http处理的详细过程,不过上表其中几行与我们的讨论是有关的:
(1)请求数据来源于/jia-hello-world/faces/hello.jsp 这个连接的POST数据。
(2)这里的referer(引用)是由请求页面产生的,他与/jia-hello-world/faces/hello.jsp是相同的页面。
(3)这里的Cookies将被Servlet容器使用,它用于将请求数据映射到一个指定的会话中。在这个例中JSF使用Servlet会话来存储当前的视图(页面也可以保存在由客户端控制的一个值对象中,比如隐藏字段中)。
(4)这是非常重要的一个部分,这里包含了JSF传输的实际参数值(&用于分隔不同的参数,%3A将被解析为“:”冒号)。首先是一个名为 welcomeForm:helloInput的参数,并且它的值是64,这个值是通过浏览器页面输入的,第二个参数名为welcomeForm: redisplayCommand,他的值是“Redisplay”,最后一个参数是welcomeForm,它的值也是welcomeForm。在下面 的讲解中我们将逐步介绍这些值是如何处理的。
        一旦JSF接收到请求,它就会创建并实例化一个javax.faces.context.FacesContext对象。这个对象代表当前的请求状态,并且负责处理底层Servlet request对象的各个部分,事件监听器可以通过它获得当前页面的操作句柄,以此来进行增加消息、记录事件等等操作。在JSF中它代表了请求处理生命周期的整个过程。我们将在下面的讲解中依次讨论每一个状态。


    摘要:

之前我们讨论了不同的JSF组件,那么如果发生错误是会怎样呢?现在最大的问题是如何让UI组件显示一个恰当的错误消息。这个消息可以分为两种:一种是应用程序错误(比如应用程序逻辑错误,数据库错误,连接错误等等),另一种是用户输入错误(比如文本框输入校验和空值校验等等)。

应 用程序错误一般会产生一个新的页面以便显示错误消息;而用户输入错误一般会回显原来的页面,然后把错误信息显示在一个文本中。通常你    (全文共2485字)——点击此处阅读全文


第1页,共2页