未对commandButton JSF 2.2启动操作



我是JSF的新手,我对非常简单的Facelets视图有一个问题:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core" >
<h:head>
<title></title>
</h:head>
<h:body>
<h:form id="form">
<h:panelGrid id="ciccio" columns="2">
<h:outputText value="Nome " />
<h:inputText value="#{thinBean.nome}" />
<h:commandButton id="ok" value="OK"  />
<h:commandButton id="vai" value="Go" rendered="#{not empty thinBean.nome}" action="Vista1" />
</h:panelGrid>
</h:form>
</h:body>
</html>

和我简单的背豆。

package magazzino;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class ThinBean implements Serializable {
private String nome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}   

第一次呼叫后,只显示第一个按钮。当我在字段nome上输入test并通过单击由ok标识的按钮提交此表单时,还会出现第二个按钮。

当我点击由vai标识的第二个按钮时,什么都没有发生:Vista1没有被渲染。

我不理解这种行为:为什么跳过调用应用程序阶段?

感谢

UICommand组件的rendered属性在应用请求值阶段也进行了评估,作为防止被篡改/黑客入侵请求的一部分,例如,黑客试图调用UICommand组件的操作,而这些操作不是为非管理员用户呈现的。

在您的特定情况下,您使用的是一个请求范围的bean。因此,bean在每个请求结束时被销毁,并在每个请求开始时被重新创建。通过第一个按钮提交表单算作一个请求。通过第二个按钮提交表单算作另一个请求。

在更新模型值阶段,UIInput值被设置为托管bean属性,这是在应用请求值阶段之后的。因此,当按下第二个按钮时,将新建请求范围的bean,并将所有属性设置为默认值(null)。在应用请求值阶段,rendered属性正在检查输入值,但尚未设置,并且bean是新的且为空的。因此,它不会将按钮视为已渲染,并跳过对动作事件的解码。

如果您将bean放在视图范围中,那么它会起作用,原因很简单,只要您通过返回nullvoid与同一视图交互,视图范围的bean实例就会一直存在。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped

另一种选择是检查rendered属性中的原始HTTP请求参数,而不是模型值。

<h:inputText binding="#{nome}" value="#{thinBean.nome}" />
<h:commandButton id="ok" value="OK"  />
<h:commandButton id="vai" value="Go" rendered="#{not empty param[nome.clientId]}" action="Vista1" />

另请参阅:

  • 如何选择正确的bean范围

最新更新