2

对于我的项目,我想用h:selectOneMenu实现一个组合框。我阅读了许多关于如何正确处理 selectOneMenu 以及如何实现自定义转换器的帖子。组合框应存储来自不同 DB 表(名为 fk_ID)的 ID(Long),该表有一个约束。到目前为止,一切似乎都按计划进行。现在我的问题:

fk_ID 列是可选的,因此组合框中的第一个选项是f:selectItem,没有标记为“choose ...”的值。当我保存表单并更改值时,一切正常,除非我将其设置回“选择...”。我得到的错误是约束完整性违规

我也发现了问题:转换器按预期返回null但 bean 收到Long 0

XHTML:

<h:selectOneMenu value="#{userBean.selectedModel.fk_id}"
    id="combobox">
    <f:selectItem itemLabel="choose ..." />
    <f:selectItems
        value="#{userBean.items}"
        var="item"
        itemLabel="#{item.value}"
        itemValue="#{item.id}"
    />
    <f:converter converterId="userConverter" />
</h:selectOneMenu>

自定义转换器:

@FacesConverter(value = "userConverter")
public class UserConverter implements Converter {
    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
        if (arg2 != null && !arg2.equals("null"))
            return Long.valueOf(arg2);

        return null;
    }
    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
        return String.valueOf(arg2);
    }
}

bean(非常短的版本):

@Named(value = "userBean")
public class UserController implements Serializable {

    @Getter
    @Setter
    private UserModel selectedModel;

    @Getter
    @Setter
    private List<UserModel> items;

    public void saveModel() {
        selectedModel = userService.saveModel(selectedModel);
    }
}

问题是fk_idLong 0,但应该是null。我可以通过写来解决问题

if (selectedModel.getFk_id() == 0)
    selectedModel.setFk_id(null);

,但这不是我喜欢的解决方案。

我的问题:为什么转换器返回的值nullsaveModel()方法中的Long 0

4

1 回答 1

5

这个转换器是不必要的并且没有意义(我希望 an在and之间UserConverter转换,而不是在and之间)。去掉它。UserStringLongString

现在,您需要告诉 JSF 将提交的空字符串值解释为null. 将以下内容添加到您的web.xml:

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

这应该可以解决大多数容器的问题。但是,如果您使用 Tomcat 或它的 fork/clone(JBoss AS、WebSphere AS 等)和/或容器使用 Apache EL 解析器实现,那么您还需要将以下参数添加到其 VM 启动参数中:

-Dorg.apache.el.parser.COERCE_TO_ZERO=false

这将防止 Apache EL 解析器将提交的值强制为原始的默认值,即使您使用原始包装器类型作为属性。

也可以看看:


与具体问题无关,您那里没有组合框。这只是一个简单的下拉列表。组合框是一个可编辑的下拉列表。让你的条款正确;)

于 2011-11-11T12:39:05.537 回答