The immediate attribute in JSF is commonly misunderstood. If you don’t believe me, check out Stack Overflow. Part of the confusion is likely due to immediate being available on both input (i.e.. <h:inputText />) and command (i.e. <h:commandButton />) components, each of which affects the JSF lifecycle differently.

Here is the standard JSF lifecycle:

 

For the purposes of this article, I’ll assume you are familiar with the basics of the JSF lifecycle. If you need an introduction or a memory refresher, check out the Java EE 6 Tutorial – The Lifecycle of a JavaServer Faces Application.

Note: the code examples in this article are for JSF 2 (Java EE 6), but the principals are the same for JSF 1.2 (Java EE 5).

immediate=true on Command components

In the standard JSF lifecycle, the action attribute on an Command component is evaluated in the Invoke Applicationphase. For example, say we have a User entity/bean:

01 public class User implements Serializable {
02  @NotBlank
03  @Length(max = 50)
04  private String firstName;
05  
06  @NotBlank
07  @Length(max = 50)
08  private String lastName;
09  
10  /* Snip constructors, getters/setters, a nice toString() method, etc */
11 }

And a UserManager to serve as our managed bean:

01 @SessionScoped
02 @ManagedBean
03 public class UserManager {
04  private User newUser;
05  
06  /* Snip some general page logic... */
07  
08  public String addUser() {
09   //Snip logic to persist newUser
10  
11   FacesContext.getCurrentInstance().addMessage(null,
12     new FacesMessage("User " + newUser.toString() + " added"));
13  
14   return "/home.xhtml";
15  }

And a basic Facelets page, newUser.xhtml, to render the view:

01 <h:form>
02  <h:panelGrid columns="2">
03  
04   <h:outputText value="First Name: " />
05   <h:panelGroup>
06    <h:inputText id="firstName"
07     value="#{userManager.newUser.firstName}" />
08    <h:message for="firstName" />
09   </h:panelGroup>
10  
11   <h:outputText value="Last Name: " />
12   <h:panelGroup>
13    <h:inputText id="lastName" value="#{userManager.newUser.lastName}" />
14    <h:message for="lastName" />
15   </h:panelGroup>
16  
17  </h:panelGrid>
18  
19  <h:commandButton value="Add User" action="#{userManager.addUser()}" />
20 </h:form>

Which all combine to produce this lovely form:

When the user clicks on the Add User button, #{userManager.addUser} will be called in the Invoke Application phase; this makes sense, because we want the input fields to be validated, converted, and applied to newUser before it is persisted.

Now let’s add a “cancel” button to the page, in case the user changes his/her mind. We’ll add another <h:commandButton /> to the page:

1 <h:form>
2  <!-- Snip Input components -->
3  
4  <h:commandButton value="Add User" action="#{userManager.addUser()}" />
5  <h:commandButton value="Cancel" action="#{userManager.cancel()}" />
6 </h:form>

And the cancel() method to UserManager:

1 public String cancel() {
2  newUser = new User();
3  
4  FacesContext.getCurrentInstance().addMessage(null,
5    new FacesMessage("Cancelled new user"));
6  
7  return "/home.xhtml";
8 }

Looks good, right? But when we actually try to use the cancel button, we get errors complaining that first and last name are required:

This is because #{userManager.cancel} isn’t called until the Invoke Application phase, which occurs after the Process Validations phase; since we didn’t enter a first and last name, the validations failed before #{userManager.cancel} is called, and the response is rendered after the Process Validations phase.

We certainly don’t want to require the end user to enter a valid user before cancelling! Fortunately, JSF provides theimmediate attribute on Command components. When immediate is set to true on an Command component, the action is invoked in the Apply Request Values phase:

This is perfect for our Cancel use case. If we add immediate=true to the Cancel , #{userManager.cancel} will be called in the Apply Request Values phase, before any validation occurs.

1 <h:form
2  <!-- Snip Input components -->
3  
4  <h:commandButton value="Add User" action="#{userManager.addUser()}" />
5  <h:commandButton value="Cancel" action="#{userManager.cancel()}" immediate="true"/>
6 </h:form>

So now when we click cancel, #{userManager.cancel} is called in the Apply Request Values phase, and we are directed back to the home page with the expected cancellation message; no validation errors!

 

What about Input components?

Input components have the immediate attribute as well, which also moves all their logic into the Apply Request Valuesphase. However, the behavior is slightly different from Command components, especially depending on whether or not the validation on the Input component succeeds. My next article will address immediate=true on Input components. For now, here’s a preview of how the JSF lifecycle is affected:

 
 

摘自:https://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html

关于JSF中immediate属性的总结(二)的更多相关文章

  1. 关于JSF中immediate属性的总结(三)

    Okay, when should I use the immediate attribute? If it isn't entirely clear yet, here's a summary, c ...

  2. 关于JSF中immediate属性的总结(一)

    Purpose The immediate attribute can be used to achieve the following effects: Allow a commandLink or ...

  3. 【Spring源码解读】bean标签中的属性(二)你可能还不够了解的 abstract 属性和 parent 属性

    abstract 属性说明 abstract 在java的语义里是代表抽象的意思,用来说明被修饰的类是抽象类.在Spring中bean标签里的 abstract 的含义其实也差不多,表示当前bean是 ...

  4. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  5. 使用虚幻引擎中的C++导论(二-UE4基类)

    使用虚幻引擎中的C++导论(二) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如果有不 ...

  6. Javascript中length属性的总结

    Javascript中length属性的总结 一.StringObject中的length     length属性是返回字符串的字符数目. 例如: // 普通字符串 var str = " ...

  7. OC中@property属性关键字的使用(assign/weak/strong/copy)

    OC中@property属性关键字的使用(assign/weak/strong/copy) 一.assign 用于 ‘基本数据类型’.‘枚举’.‘结构体’ 等非OC对象类型 eg:int.bool等 ...

  8. CSS3中动画属性transform、transition 和 animation

    CSS3中和动画有关的属性有三个 transform.transition 和 animation.下面来一一说明:        transform   从字面来看transform的释义为改变,使 ...

  9. 【转】WPF中的Binding技巧(二)

    WPF中的Binding技巧(二)     接上篇, 我们来看一看Elementname,Source,RelativeSource 三种绑定的方式 1.ElementName顾名思义就是根据Ui元素 ...

随机推荐

  1. Android快乐贪吃蛇游戏实战项目开发教程-02虚拟方向键(一)自定义控件概述

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.自定义控件简介 在本项目中,无论是游戏主区域还是虚拟方向键都是通过自定义控件 ...

  2. SCNU 2015ACM新生赛初赛【1006. 3D打印】解题报告

            题目链接详见SCNU 2015新生网络赛 1006. 3D打印 .出题思路来自codevs 3288. 积木大赛,属于模拟题.         首先我们把“选择从第L部分到第R部分”理 ...

  3. BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: ...

  4. [KMP]【学习笔记】

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36916   Accepted: 14904 Descript ...

  5. [AR]ImageTarget(图像识别)

    ImageTarget 前言 ImageTarget 顾名思义,就是图像识别,本文记录下作者最近学习vuforia中的imageTarget笔记与心得. vuforia guide:https://l ...

  6. Nginx模块之http.md

    ngx_http_access_module ngx_http_access_module模块允许限制对某些客户端地址的访问. 访问也可以通过密码,子请求的结果或JWT来限制. 通过地址和密码的同时访 ...

  7. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  8. 「坐上时光机,查找编译压缩后的文件最初的样子」gulp-sourcemaps 使用说明

    一般我们调试的 js/css 文件都是编译压缩后的,一旦出错很难定位原始的位置,gulp-sourcemaps 的出现帮助我们解决了这个问题. 首先我们看下目录结构: css js a.js b.js ...

  9. [板子]ISAP

    ISAP求最大流,敲了一发板子,无压行,教程略去.转载请随意. #include <cstdio> #include <cstring> #include <algori ...

  10. Nfs+Drdb+Heartbeat 数据存储高可用服务架构方案

    一.方案的应用场景 适用于2千万-3千万PV架构的网站,Nfs数据存储高可用服务方案 备注:互联网排名前30左右公司常用的架构 二.生产环境方案部署原理图 三.生产环境服务器硬件配置: 生产环境中采用 ...