在JSF中验证错误后丢失的值

时间:2009-12-17 22:43:38

标签: jsf

我有两页。搜索页面是获取用户输入的第一页。第二页显示了数据表中的结果集。第二页有3个面板用于结果集,更新并在单页中创建所有。根据单击的按钮,我将渲染面板设为true和false。

<h:panelGroup styleClass="panelGroup"
                id="resultSet" rendered="#{bean.truefalse1}">
.
.
</h:panelGroup

<h:panelGroup styleClass="panelGroup"
                id="updateForm" rendered="#{bean.truefalse2}">
.
.
</h:panelGroup


<h:panelGroup styleClass="panelGroup"
                id="createForm" rendered="#{bean.truefalse3}">
.
.
</h:panelGroup>

在搜索页面中,我将这些创建和更新面板设置为false并仅显示结果集。单击结果集中的行后,我显示 updateForm面板,但将create panel保持为false。

但问题是,如果存在验证错误,则从搜索页面设置的属性将丢失,并显示所有面板。

如何获取之前从搜索页面设置的值(布尔值true或false),因为我没有导航到不同的页面。

我在第二个类中有boolean属性的getter和setter。我甚至尝试保留隐藏字段(即从搜索页面设置的布尔属性)。 在验证错误后,不应恢复所有提交的值。或者只是我们在表单中输入的内容。

什么是最佳解决方案?

任何帮助都非常感谢!!!

1 个答案:

答案 0 :(得分:5)

您确实需要将相同的布尔属性传输到下一个请求。理论上,您可以使用<h:inputHidden value="#{bean.boolean1}" />,但不幸的是,这些只会在更新模型值阶段设置,而实际上您需要在应用请求值阶段使用它。此外,当发生验证错误时,它们也会丢失。

有三种方法可以解决h:inputHidden的这种非直观行为(我曾经在Mojarra问题列表中提交了一个针对它的错误,但他们似乎没有做任何事情)。< / p>

首先使用binding上的h:inputHidden代替:

<h:inputHidden binding="#{bean.hidden1}" />

但是,这需要更改在支持bean代码中获取/设置布尔值的方式。例如:

private HtmlInputHidden hidden1 = new HtmlInputHidden(); // +getter +setter.

public void setBoolean1(boolean boolean1) {
    hidden1.setValue(boolean1);
}

public boolean getBoolean1() {
    return (Boolean) hidden1.getValue();
}

其次是使用Tomahawkt:saveState代替。

<t:saveState value="#{bean.boolean1}" />

主要优点是您不需要更改支持bean代码中的任何内容。它将在应用请求值阶段之前提前恢复该值。如果还没有完成,你只需要添加额外的库,但是因为Tomahawk提供的优势远远超过t:saveState,例如基本的JSF实现缺少组件/功能t:inputFileUploadt:dataListt:dataTable preserveDataModel="true"t:selectOneRadio layout="spread"等等,值得努力。

第三种方法是将它们存储在会话范围的bean中,但实际上您不希望对请求范围的变量执行此操作。它只会给“wtf?”当最终用户在同一会话中打开多个选项卡/窗口时的体验。

根据评论

修改,这是第二种方式的SSCCE

JSF页面:

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<f:view>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
        </head>
        <body>
            <h:form id="form">
                <h:inputHidden binding="#{myBean.hidden}" converter="javax.faces.Boolean" />
                <h:commandButton value="submit" action="#{myBean.submit}"/>
                <h:outputText value="Current boolean value: #{myBean.hidden.value}" />
            </h:form>
        </body>
    </html>
</f:view>

MyBean类:

package mypackage;

import javax.faces.component.html.HtmlInputHidden;

public class MyBean {

    private HtmlInputHidden hidden = new HtmlInputHidden();

    public void submit() {
        if (hidden.getValue() == null) {
            hidden.setValue(true); // Set to true on 1st submit.
        } else {
            hidden.setValue(!((Boolean) hidden.getValue())); // Toggle true/false.
        }
    }

    public HtmlInputHidden getHidden() {
        return hidden;
    }

    public void setHidden(HtmlInputHidden hidden) {
        this.hidden = hidden;
    }

}

faces-config.xml的相关部分:

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>mypackage.MyBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

Playground环境是Tomcat 6.0.20上的JSF 1.2_13。