JSF - 1 个组件中的验证错误,导致表单中的所有其他组件失败

问题描述

大家好

我使用 JSF Mojarra 实现,版本 JSF 2.2

我非常需要这方面的帮助。

  1. 我有我的网页片段。
  2. 我在页面中使用了一个自定义组件“example_result.xhtml”。
  3. 我有我的 backingBean.java 请注意,此代码不是我制作的真正代码。如果你运行它,它会非常难看,也许是因为我删除了所有的 css 类,我只保留了我需要向你展示我的问题的热门内容

一切都在 1 个表单中。

5 "h:selectManyCheckBox"(在我的代码我有 8 或 9)

在表单中,我有 5 个“h:selectManyCheckBox”,它们在不同情况下使用“value”属性中的值(javaFrameworks2Values、javaFrameworks3Values...),“f:selectItems”使用“SelectItem”数组(javaFrameworksSelectItems2,javaFrameworksSelectItems3...) 为这些不同的情况创建,只是为了让我了解所有 selectOne 和 selectMany 组件如何工作的一些例子。 关于不同案例的想法来自以下链接: “https://stackoverflow.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), 我已经初始化:

  1. SelectItems 的值和
  2. “value”属性的值,其中将存储“h:selectManyCheckBox”的值以供稍后显示。 [代码完全阉割,使其成为可读的片段]。

页面呈现时,我从所有“h:selectManyCheckBox”中选择复选框(例如最后两个,因为前两个是首字母)。 当我说从所有中选择时,我是认真的。从第 4 个开始,带有“required属性。我在按钮中尝试(参见代码)“Effort 1”、“Effort 2”或“Effort 3”(在按钮中的“f:ajax”中)并显示最后一部分的结果输出并像糖果一样更新。没有任何问题。为了使用复合组件实现这一点,我在谷歌上搜索并尝试了很多。但我做到了。

接下来就是尝试第四次查看“required属性的验证错误

我像以前一样从所有中再次选择,但不是从所有中选择。这次不是来自第 4 个“h:selectManyCheckBox”。我没有从第 4 个“h:selectManyCheckBox”中选择任何内容来检查验证器错误消息(“requiredMessage”)。 结果是: 它显示错误消息(到目前为止良好),但这次它不会将其他“h:selectManyCheckBox”中的任何内容更新到最后的输出结果,并且它不会像以前那样重置值(当我从所有和第 4 个中选择时)。

我知道它说:只要表单中的第 4 个因验证错误而失败,所有其他“h:selectManyCheckBox”都不会更新输出结果(就像想让所有其他人都失败一样)。

>

但这里到底发生了什么?

  1. 它没有为“h:selectManyCheckBox”提供值以更新到输出
  2. 它通常会为“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: "MybackingBean.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),我决定发布我的解决方案:

我将使用 5 组按钮(提交/重置)制作 5 个不同的表单,以便将这个问题升级到表单中的 5 个相关组件。

但我的问题是开放的: 为什么会发生这种情况,在这种情况下 JSF 中正在发生什么规则并造成这种情况。 任何人,都有解释:

  • Thomas:这是 JSF 中的规则,或者
  • 是一个 JSF 错误,或者
  • 这种情况会发生在这些情况下,或者……无论如何……

我会很高兴在这里阅读它,这样我会学得更好,其他人也会从你的这些想法中学习。 非常感谢