关于JSF中immediate属性的总结(二)

 

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:

01public 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
03public 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:

1public 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

转载于:https://www.cnblogs.com/fuzhihong0917/p/6133054.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值