JSF - 1 个组件中的验证错误,导致表单中的所有其他组件失败
JSF - Validation error in 1 component, leads all others in the form to fail
大家好
我使用 JSF Mojarra 实现,版本 JSF 2.2
我急需帮助。
- 我有一个页面片段。
- 我在页面中使用了自定义组件“example_result.xhtml”。
- 我有我的BackingBean.java
请注意,此代码不是我编写的真实代码。如果你 运行 它,它会非常丑陋,可能是因为我删除了所有 css 类 并且我只保留了我需要向你展示我的问题的热门内容。
一切都在 1 个表格中。
5个“h:selectManyCheckbox”(在我的代码中我有8个或9个)
在表单中,我有 5 个“h:selectManyCheckbox”,它们在不同情况下使用“value”属性中的值(javaFrameworks2Values、javaFrameworks3Values,...),以及“f:selectItems”使用为这些不同情况创建的“SelectItem”数组(javaFrameworksSelectItems2、javaFrameworksSelectItems3...),只是为了让我了解所有 selectOne 和 select许多组件工作。
关于不同案例的想法来自这些链接:
“https://whosebug.com/tags/selectonemenu/info”和
"https://mkyong.com/jsf2/jsf-2-checkboxes-example".
在我有 2 个命令按钮后
1 个用于提交,1 个用于重置值。
显示值
在我通过“example_result.xhtml”显示“h:selectManyCheckbox”的值的结果后。
您可以看到第 4 个“h:selectManyCheckbox”,这是唯一不同的,因为它具有属性“required”和属性“requiredMessage”。它有一个“h:message”来显示验证错误。
在 BackingBean(它是 Spring Bean,但它工作得很好 - 抱歉我不想要 ejbs 3.x),
我已经初始化:
- SelectItems 的值和
- “value”属性的值,其中将存储“h:selectManyCheckbox”的值以供稍后显示。
[代码完全阉割,使其成为可读片段]。
呈现页面时,我从所有“h:selectManyCheckbox”中选择 select 个复选框(例如,最后两个,因为前两个是首字母)。
当我说 select from all 时,我是认真的。从 4 号开始,具有“必需”属性。我尝试在按钮中(参见代码)“努力 1”或“努力 2”或“努力 3”(在按钮中的“f:ajax”中)并将结果输出到最后一部分像糖果一样显示和更新。没有任何问题。为了用复合组件实现这一点,我在谷歌上搜索并尝试了很多。但是我做到了。
然后是时候尝试第 4 次,看看“required”属性的验证错误。
我select 再次从所有像以前一样,但不是从所有。这次不是来自第 4 个“h:selectManyCheckbox”。我 select 没有从第 4 个“h:selectManyCheckbox”中检查验证程序错误消息(“requiredMessage”)。
结果是:
它显示错误消息(到目前为止还不错),但是这次它没有将其他“h:selectManyCheckbox”中的任何内容更新到最后的输出结果,也没有重置值就像以前一样(当我 select 从所有和第 4 次开始编辑时)。
我知道它说:只要在表单中第 4 个因验证错误而失败,所有其他“h:selectManyCheckbox”将不会更新输出结果(类似于想要全部失败其他人也是)。
但是这里到底发生了什么?
- 它没有为要更新到输出的“h:selectManyCheckbox”提供值?
- 它通常将值提供给“h:selectManyCheckbox”,但它只是不更新输出?
按钮中“f:ajax”的其他努力,可能只是为了解决问题而努力,但在这些情况下,它们甚至不显示第 4 种情况下的错误消息他们也不会(再次)更新其他输出结果。但是也没有消息错误。
不知道你是否清楚这个问题。我可以在讨论中更好地解释,这样我就可以更好地澄清情况。
[老实说,我花了1个半小时才写完这些东西]
提前致谢
========== 来自我页面的片段 ==========
<h:form>
<h:panelGrid id="smcb" columns="1">
<h:selectManyCheckbox id="smcb1" value="#{myBackingBean.javaFrameworksHardCodedValues}">
<f:selectItem itemLabel="Java Label" itemValue="Java Value"/>
<f:selectItem itemLabel="Spring Framework Label" itemValue="Spring Framework Value"/>
<f:selectItem itemLabel="Hibernate Label" itemValue="Hibernate Value"/>
<f:selectItem itemLabel="JSF Framework Label" itemValue="JSF Framework Value"/>
</h:selectManyCheckbox>
<h:selectManyCheckbox id="smcb2" value="#{myBackingBean.javaFrameworks2Values}">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems2}"/>
</h:selectManyCheckbox>
<h:selectManyCheckbox id="smcb3" value="#{myBackingBean.javaFrameworks3Values}">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems3}"/>
</h:selectManyCheckbox>
<p><h:message for="smcb4" styleClass="error_messages"/></p>
<h:selectManyCheckbox id="smcb4" value="#{myBackingBean.javaFrameworks4Values}"
required="true"
requiredMessage="The 'h:selectManyCheckbox' must have a value. Please select an item from the list!">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems4}"/>
</h:selectManyCheckbox>
<h:selectManyCheckbox id="smcb5" value="#{myBackingBean.javaFrameworks5Values}">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems5}"/>
</h:selectManyCheckbox>
</h:panelGrid>
<br/>
<h:commandButton value="Display Java Frameworks values">
<!--
Effort 1 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb1 smcb2 smcb3 smcb4 smcb5 smcb6 smcb7 smcb8"
render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
-->
<!--
Effort 2 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb" render="outputId smcb"/>
-->
<!--
Effort 3 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="@form" render="@form"/>
-->
<!--
Not working efforts to solve my problem - but are not solving it
<f:ajax execute="@form" render="outputId"/>-->
<f:ajax execute="@form"
render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
Other combinations with the @form and the ids...
-->
</h:commandButton>
<h:commandButton value="Reset Java Frameworks values" action="#{myBackingBean.resetValues}">
<!--
Effort 1 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb1 smcb2 smcb3 smcb4 smcb5"
render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
-->
<!--
Effort 2 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb" render="outputId smcb"/>
-->
<!--
Effort 3 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="@form" render="@form"/>
-->
</h:commandButton>
<br/>
<h:panelGrid columns="1" id="outputId">
<mc:example_result id="outputId1"
example_label="1. Java Frameworks hardcoded with 'f:selectItem': "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId2"
example_label="2. Java Frameworks 2: "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId3"
example_label="3. Java Frameworks 3: "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId4"
example_label="4. Java Frameworks 4: "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId5"
example_label="5. Java Frameworks 5: "
example_result="#{myBackingBean.displayItemValues()}"/>
</h:panelGrid>
</h:form>
========== 我的组件:“example_result.xhtml” ==========
<ui:composition ...
xmlns:mc="http://xmlns.jcp.org/jsf/composite/mc_components">
<cc:interface>
<cc:attribute name="example_label" type="java.lang.String" required="true"/>
<cc:attribute name="example_result" type="java.lang.String" required="true"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:outputText value="#{cc.attrs.example_label}" .../>
<h:outputText value="#{cc.attrs.example_result}" .../>
</div>
</cc:implementation>
</ui:composition>
========== 我的 BackingBean:“我的BackingBean.java” ==========
@org.springframework.stereotype.Component(value = "myBackingBean")
public class MyBackingBean implements Serializable {
// Variables used in the "value" attribute of "HtmlSelectMany" components
private String[] javaFrameworks2Values; // + Getters-Setters
// All the others: javaFrameworks3Values, ...
// The "HtmlSelects" components' "SelectItems" are generated by an array of "SelectItem"
private SelectItem[] javaFrameworksSelectItems2; // +Getters
// All the others: javaFrameworksSelectItems3, ...
@PostConstruct
protected void initLabelValueMapAndLabelValueArray() {
// Pre-selected values of "HtmlSelectMany" components
javaFrameworks2Values = new String[]{"Java Value", "Spring Framework Value"};
// Initialization of the array of "SelectItem"
javaFrameworksSelectItems2 = new SelectItem[4];
javaFrameworksSelectItems2[0] = new SelectItem("Java Value", "Java Label");
javaFrameworksSelectItems2[1] = new SelectItem("Spring Framework Value", "Spring Framework Label");
javaFrameworksSelectItems2[2] = new SelectItem("Hibernate Value", "Hibernate Label");
javaFrameworksSelectItems2[3] = new SelectItem("JSF Framework Value", "JSF Framework Label");
// Initialization of all the others: javaFrameworks3Values, ..., javaFrameworksSelectItems3, ...
}
public String displayItemValues() {
// return array of the result values;
}
public void resetValues() {
// Reset the values to the initials
}
}
在与这里唯一想帮助解决我的问题的人进行大量讨论后(我非常感谢他@WoAiNii),我决定 post 我的解决方案:
我将使用 5 组按钮制作 5 种不同的表单 (submit/reset),以升级此问题,因为表单中有 5 个如此多的相关组件。
但我的问题是开放的:
为什么会发生这种情况,在这种情况下,JSF 中的什么规则正在发生并造成这种情况。
任何有解释的人,例如:
- 这是 JSF 中的规则,或者
- 是一个 JSF 错误,或者
- 在这些情况下会发生这种情况,或者...无论如何...,
我很高兴在这里阅读它,这样我会学得更好,其他人也会从你的这些想法中学习。
非常感谢
大家好
我使用 JSF Mojarra 实现,版本 JSF 2.2
我急需帮助。
- 我有一个页面片段。
- 我在页面中使用了自定义组件“example_result.xhtml”。
- 我有我的BackingBean.java 请注意,此代码不是我编写的真实代码。如果你 运行 它,它会非常丑陋,可能是因为我删除了所有 css 类 并且我只保留了我需要向你展示我的问题的热门内容。
一切都在 1 个表格中。
5个“h:selectManyCheckbox”(在我的代码中我有8个或9个)
在表单中,我有 5 个“h:selectManyCheckbox”,它们在不同情况下使用“value”属性中的值(javaFrameworks2Values、javaFrameworks3Values,...),以及“f:selectItems”使用为这些不同情况创建的“SelectItem”数组(javaFrameworksSelectItems2、javaFrameworksSelectItems3...),只是为了让我了解所有 selectOne 和 select许多组件工作。 关于不同案例的想法来自这些链接: “https://whosebug.com/tags/selectonemenu/info”和 "https://mkyong.com/jsf2/jsf-2-checkboxes-example".
在我有 2 个命令按钮后
1 个用于提交,1 个用于重置值。
显示值
在我通过“example_result.xhtml”显示“h:selectManyCheckbox”的值的结果后。
您可以看到第 4 个“h:selectManyCheckbox”,这是唯一不同的,因为它具有属性“required”和属性“requiredMessage”。它有一个“h:message”来显示验证错误。
在 BackingBean(它是 Spring Bean,但它工作得很好 - 抱歉我不想要 ejbs 3.x), 我已经初始化:
- SelectItems 的值和
- “value”属性的值,其中将存储“h:selectManyCheckbox”的值以供稍后显示。 [代码完全阉割,使其成为可读片段]。
呈现页面时,我从所有“h:selectManyCheckbox”中选择 select 个复选框(例如,最后两个,因为前两个是首字母)。 当我说 select from all 时,我是认真的。从 4 号开始,具有“必需”属性。我尝试在按钮中(参见代码)“努力 1”或“努力 2”或“努力 3”(在按钮中的“f:ajax”中)并将结果输出到最后一部分像糖果一样显示和更新。没有任何问题。为了用复合组件实现这一点,我在谷歌上搜索并尝试了很多。但是我做到了。
然后是时候尝试第 4 次,看看“required”属性的验证错误。
我select 再次从所有像以前一样,但不是从所有。这次不是来自第 4 个“h:selectManyCheckbox”。我 select 没有从第 4 个“h:selectManyCheckbox”中检查验证程序错误消息(“requiredMessage”)。 结果是: 它显示错误消息(到目前为止还不错),但是这次它没有将其他“h:selectManyCheckbox”中的任何内容更新到最后的输出结果,也没有重置值就像以前一样(当我 select 从所有和第 4 次开始编辑时)。
我知道它说:只要在表单中第 4 个因验证错误而失败,所有其他“h:selectManyCheckbox”将不会更新输出结果(类似于想要全部失败其他人也是)。
但是这里到底发生了什么?
- 它没有为要更新到输出的“h:selectManyCheckbox”提供值?
- 它通常将值提供给“h:selectManyCheckbox”,但它只是不更新输出?
按钮中“f:ajax”的其他努力,可能只是为了解决问题而努力,但在这些情况下,它们甚至不显示第 4 种情况下的错误消息他们也不会(再次)更新其他输出结果。但是也没有消息错误。
不知道你是否清楚这个问题。我可以在讨论中更好地解释,这样我就可以更好地澄清情况。 [老实说,我花了1个半小时才写完这些东西]
提前致谢
========== 来自我页面的片段 ==========
<h:form>
<h:panelGrid id="smcb" columns="1">
<h:selectManyCheckbox id="smcb1" value="#{myBackingBean.javaFrameworksHardCodedValues}">
<f:selectItem itemLabel="Java Label" itemValue="Java Value"/>
<f:selectItem itemLabel="Spring Framework Label" itemValue="Spring Framework Value"/>
<f:selectItem itemLabel="Hibernate Label" itemValue="Hibernate Value"/>
<f:selectItem itemLabel="JSF Framework Label" itemValue="JSF Framework Value"/>
</h:selectManyCheckbox>
<h:selectManyCheckbox id="smcb2" value="#{myBackingBean.javaFrameworks2Values}">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems2}"/>
</h:selectManyCheckbox>
<h:selectManyCheckbox id="smcb3" value="#{myBackingBean.javaFrameworks3Values}">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems3}"/>
</h:selectManyCheckbox>
<p><h:message for="smcb4" styleClass="error_messages"/></p>
<h:selectManyCheckbox id="smcb4" value="#{myBackingBean.javaFrameworks4Values}"
required="true"
requiredMessage="The 'h:selectManyCheckbox' must have a value. Please select an item from the list!">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems4}"/>
</h:selectManyCheckbox>
<h:selectManyCheckbox id="smcb5" value="#{myBackingBean.javaFrameworks5Values}">
<f:selectItems value="#{myBackingBean.javaFrameworksSelectItems5}"/>
</h:selectManyCheckbox>
</h:panelGrid>
<br/>
<h:commandButton value="Display Java Frameworks values">
<!--
Effort 1 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb1 smcb2 smcb3 smcb4 smcb5 smcb6 smcb7 smcb8"
render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
-->
<!--
Effort 2 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb" render="outputId smcb"/>
-->
<!--
Effort 3 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="@form" render="@form"/>
-->
<!--
Not working efforts to solve my problem - but are not solving it
<f:ajax execute="@form" render="outputId"/>-->
<f:ajax execute="@form"
render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
Other combinations with the @form and the ids...
-->
</h:commandButton>
<h:commandButton value="Reset Java Frameworks values" action="#{myBackingBean.resetValues}">
<!--
Effort 1 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb1 smcb2 smcb3 smcb4 smcb5"
render="outputId1 outputId2 outputId3 outputId4 outputId5 smcb1 smcb2 smcb3 smcb4 smcb5"/>
-->
<!--
Effort 2 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="smcb" render="outputId smcb"/>
-->
<!--
Effort 3 - works perfectly good if I select from all the "h:selectManyCheckbox"
<f:ajax execute="@form" render="@form"/>
-->
</h:commandButton>
<br/>
<h:panelGrid columns="1" id="outputId">
<mc:example_result id="outputId1"
example_label="1. Java Frameworks hardcoded with 'f:selectItem': "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId2"
example_label="2. Java Frameworks 2: "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId3"
example_label="3. Java Frameworks 3: "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId4"
example_label="4. Java Frameworks 4: "
example_result="#{myBackingBean.displayItemValues()}"/>
<mc:example_result id="outputId5"
example_label="5. Java Frameworks 5: "
example_result="#{myBackingBean.displayItemValues()}"/>
</h:panelGrid>
</h:form>
========== 我的组件:“example_result.xhtml” ==========
<ui:composition ...
xmlns:mc="http://xmlns.jcp.org/jsf/composite/mc_components">
<cc:interface>
<cc:attribute name="example_label" type="java.lang.String" required="true"/>
<cc:attribute name="example_result" type="java.lang.String" required="true"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:outputText value="#{cc.attrs.example_label}" .../>
<h:outputText value="#{cc.attrs.example_result}" .../>
</div>
</cc:implementation>
</ui:composition>
========== 我的 BackingBean:“我的BackingBean.java” ==========
@org.springframework.stereotype.Component(value = "myBackingBean")
public class MyBackingBean implements Serializable {
// Variables used in the "value" attribute of "HtmlSelectMany" components
private String[] javaFrameworks2Values; // + Getters-Setters
// All the others: javaFrameworks3Values, ...
// The "HtmlSelects" components' "SelectItems" are generated by an array of "SelectItem"
private SelectItem[] javaFrameworksSelectItems2; // +Getters
// All the others: javaFrameworksSelectItems3, ...
@PostConstruct
protected void initLabelValueMapAndLabelValueArray() {
// Pre-selected values of "HtmlSelectMany" components
javaFrameworks2Values = new String[]{"Java Value", "Spring Framework Value"};
// Initialization of the array of "SelectItem"
javaFrameworksSelectItems2 = new SelectItem[4];
javaFrameworksSelectItems2[0] = new SelectItem("Java Value", "Java Label");
javaFrameworksSelectItems2[1] = new SelectItem("Spring Framework Value", "Spring Framework Label");
javaFrameworksSelectItems2[2] = new SelectItem("Hibernate Value", "Hibernate Label");
javaFrameworksSelectItems2[3] = new SelectItem("JSF Framework Value", "JSF Framework Label");
// Initialization of all the others: javaFrameworks3Values, ..., javaFrameworksSelectItems3, ...
}
public String displayItemValues() {
// return array of the result values;
}
public void resetValues() {
// Reset the values to the initials
}
}
在与这里唯一想帮助解决我的问题的人进行大量讨论后(我非常感谢他@WoAiNii),我决定 post 我的解决方案:
我将使用 5 组按钮制作 5 种不同的表单 (submit/reset),以升级此问题,因为表单中有 5 个如此多的相关组件。
但我的问题是开放的: 为什么会发生这种情况,在这种情况下,JSF 中的什么规则正在发生并造成这种情况。 任何有解释的人,例如:
- 这是 JSF 中的规则,或者
- 是一个 JSF 错误,或者
- 在这些情况下会发生这种情况,或者...无论如何...,
我很高兴在这里阅读它,这样我会学得更好,其他人也会从你的这些想法中学习。 非常感谢