h:selectOneRadio 映射到布尔值正在将 null 转换为 false

h:selectOneRadio mapped to a Boolean value is converting nulls to false

我有一个 h:selectOneRadio 组件,我已将其映射到支持 bean 中的 Boolean(不是布尔值)。加载时,单选按钮没有默认 select 选项,并且单选按钮不是必填字段。

示例代码:

JSF 页面摘录:

<h:form>
<h:selectOneRadio value="#{pagecode.test}">
    <f:selectItem itemValue="#{true}" itemLabel="Yes"/>
    <f:selectItem itemValue="#{false}" itemLabel="No"/>
</h:selectOneRadio>
<h:commandButton value="Save" action="#{pagecode.save}"/>
</h:form> 

支持 Java 页面代码:

package pagecode;

public class JSFBooleanTestView extends PageCodeBase {

    protected Boolean test;

    public Boolean getTest() {
        return test;
    }

    public void setTest(Boolean test) {
        this.test = test;
    } 

    public String save() {
        return "JSFBooleanTestView";
    }
}

面孔-config.xml摘录:

<managed-bean>
    <managed-bean-name>pagecode</managed-bean-name>
    <managed-bean-class>pagecode.JSFBooleanTestView</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

由于 test 没有默认值,因此单选按钮开始未 selected。由于该字段不是必需的,我的预期是按下没有单选按钮 selected 的保存按钮会导致测试为空。相反,测试被分配为假。

我尝试过但没有效果的不同选项:

  1. 设置h:selectOneRadio required="false"

  2. 添加到web.xml:

    <context-param>
         <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
         <param-value>true</param-value>
     </context-param>
    
  3. 添加到web.xml:

     <context-param>
         <param-name>org.apache.el.parser.COERCE_TO_ZERO</param-name>
         <param-value>false</param-value>
     </context-param>
    

工作是将 immediate="true" 添加到 h:commandButton

我的问题:

  1. 是什么让 h:selectOneRadio 正常将 null 转换为 false?这是预期的行为吗?

  2. 为什么 immediate="true" 使 h:commandButton 不将空值转换为假值? immediate="true" 在这种导致差异的特定情况下究竟做了什么不同的事情?我知道 immediate="true" 将跳过 JSF 生命周期中的某些阶段,但我不明白在这些阶段中是什么导致了从 null 到 false 的转换。

编辑:

我刚刚意识到我将 immediate="true" 添加到 h:commandButton 而不是 h:selectOneRadio。我的问题已相应编辑。

这在使用 Apache MyFaces 2.0 的 IBM WebSphere Portal 8.0 上的 portlet 应用程序中使用。

BooleanIntegerDoubleCharacter 等基本包装器的行为获取原始默认值 false00.0\u0000 等而不是 null 分配给 Apache EL,它在 a.o 中使用。 Tomcat、JBoss AS 和 WebSphere 服务器。它只影响基于 EL 2.1 和 EL 2.2 的版本。自 EL 3.0 起,此错误行为已得到纠正(在我自己 issue report 之后)。

使用 org.apache.el.parser.COERCE_TO_ZERO 确实是解决方案,但您应该将其设置为 VM 参数(系统 属性),而不是上下文参数。对于这个特定问题,javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL 是不相关的,但您绝对应该保留它以避免 String 键入的值被设置为空字符串而不是 null.

博客文章 The empty String madness.

中详细介绍了所有这一切和一些历史

另请参阅:

  • h:inputText which is bound to Integer property is submitting value 0 instead of null