之前我已经完成了JSF工作,但我是RichFaces的新手。为了测试我的设置和环境等,我试图制作一个简单的小应用程序,用户输入两个数字,点击一个按钮,应用程序返回数字的总和和产品。
以下是代码摘要:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>eSPAR</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<!-- Plugging the skin into the project -->
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>deepMarine</param-value>
</context-param>
<!-- Making the RichFaces skin spread to standard HTML controls -->
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING</param-name>
<param-value>enable</param-value>
</context-param>
</web-app>
下一步:
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application></application>
</faces-config>
换句话说,除版本声明外基本上是空的。接下来是视图页面:
addmult.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:head>
</h:head>
<h:body>
<rich:panel header="Sample Add and Multiply App">
<h:form id="addmultForm">
<p>Enter one number here:
<rich:inputNumberSpinner id="num1" minValue="0"
value="# {calcBean.number1}" /></p>
<p>Enter another number here:
<rich:inputNumberSpinner id="num2" minValue="0"
value="#{calcBean.number2}" /></p>
<a4j:commandButton value="Go" action="#{calcBean.go}" immediate="true">
<f:ajax event="click" render="results" />
</a4j:commandButton>
<br /><br />
<h:panelGroup id="results">
<h:panelGroup rendered="#{calcBean.calcDone}">
<p>The sum of your two numbers is: #{calcBean.sum}</p>
<p>The product of your two numbers is: #{calcBean.product}</p>
</h:panelGroup>
</h:panelGroup>
</h:form>
</rich:panel>
</h:body>
</f:view>
现在终于豆了:
CalcBean.java
import javax.faces.bean.ManagedBean;
@ManagedBean
public class CalcBean {
private Integer number1 = 3;
private Integer number2 = 7;
private int sum;
private int product;
private boolean calcDone = false;
public Integer getNumber1() {
System.out.println("I am number1: " + number1);
return number1;
}
public void setNumber1(Integer number1) {
System.out.println("Change in number1");
this.number1 = number1;
}
public Integer getNumber2() {
return number2;
}
public void setNumber2(Integer number2) {
this.number2 = number2;
}
public int getSum() {
return sum;
}
public int getProduct() {
return product;
}
public boolean isCalcDone() {
System.out.println("Returning calcDone: " + calcDone);
return calcDone;
}
public String go() {
System.out.println("Going!");
sum = number1 + number2;
product = number1 * number2;
calcDone = true;
return null;
}
}
我的WEB_INF lib包含:commons-beanutils-1.8.3,commons-collections-3.2.1,commons-digester-2.1,commons-logging-1.1.1,cssparser-0.9.5,guava-r08,jhighlight- 1.0,jsf-api(mojarra 2.0版本),jsf-facelets-1.1.15,jsf-impl(再次mojarra 2.0),richfaces-components-api-4.0.0-FINAL,richfaces-components-ui-4.0.0- FINAL,richfaces-core-api-4.0.0-FINAL,richfaces-core-impl-4.0.0-FINAL,sac-1.3,标准。
无论我启动整数number1和number2的是什么值,这些都是页面加载时输入中最初的值。最初的文本最初是隐藏的。单击“开始”按钮时,将显示下方面板,但无论用户输入的值是多少,总和始终为10,产品始终为21(如图所示)。
setter中的sysout永远不会显示。当页面加载时,getter中的一个显示一次。单击“Go”时,sysout“Going!”显示一次,然后“返回calcDone:true”显示六次。
我尝试过:更改bean的范围。在<h:outputText>
的结果面板中包装表达式。在web.xml中添加FaceletViewHandler(实际上会导致更多问题)。从lib中删除facelet jar文件。
我是否需要输入值更改侦听器?我还应该尝试什么?
答案 0 :(得分:1)
<a4j:commandButton value="Go" action="#{calcBean.go}" immediate="true">
<f:ajax event="click" render="results" />
</a4j:commandButton>
删除immediate="true"
。它会导致不的输入在处理过程中被完全跳过immediate="true"
。同时删除<f:ajax>
,因为<a4j:commandButton>
已使用ajax。为了更好地理解immediate
做了什么以及你需要做什么,我建议你自己完成这篇文章:Debug JSF lifecycle(是的,它是针对JSF 1.2的,但是一般概念适用于JSF 2。 x以及)
以下是相关性摘要:
Okay, when should I use the immediate attribute?
如果还不完全清楚,这里有一个摘要,当它们可能有益时,可以使用真实世界的用例:
如果仅在
UIInput
(s)中设置,则过程验证阶段将在申请请求值阶段进行。使用此选项可以优先验证相关UIInput
组件的验证。当其中任何一个验证/转换失败时,将不会验证/转换非直接组件。如果仅在
UICommand
中设置,则应用请求值阶段直到更新模型值阶段将跳过任何UIInput
组件。使用此选项可跳过表单的整个处理过程。例如。 “取消”或“返回”按钮。如果同时在
UIInput
和UICommand
组件中设置,则应用请求值阶段直到更新模型值将跳过任何UIInput
组件的阶段没有设置此属性。使用此选项可以跳过对某些字段(即时)的整个表单的处理。例如。登录表单中的“忘记密码”按钮,其中包含必填但非直接的密码字段。
所以,你最终想要这个:
<a4j:commandButton value="Go" action="#{calcBean.go}" render="results" />
无关:您的配置中存在更严重的问题。我的印象是你正在阅读JSF 1.x和RichFaces 3.x目标教程/文档,而不是JSX 2.x和RichFaces 4.x目标教程。第一个<context-param>
仅对JSF 1.x Facelets是强制性的,而补余都是RichFaces 3.x特有的。全部删除它们。您还有一个违规的JSF 1.x jsf-facelets.jar
文件应该被删除,而JSF 2.x已经捆绑了JSF 2.x Facelets实现。