5

我正在尝试创建一个简单的 crud 表单来使用休眠将数据插入数据库,而不知道对象类型是什么。最终目标是数据库中的每个表只有一个插入表单。到目前为止,我得到了当前对象具有的方法,检查它是否具有任何设置方法,并为每个具有集合的字段创建一个文本输入。

UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
HtmlPanelGrid hpg = (HtmlPanelGrid) viewRoot.findComponent("panel");
    for (Method method : declaredFields) {
        String name = method.getName();

        if (name.contains("set")) {
            HtmlOutputText hot = new HtmlOutputText();
            HtmlInputText hit = new HtmlInputText();
            hot.setValue(name.substring(3));
            try {
                hit.setValue(newObject.getClass().getMethod(name, String.class));
            } catch (Exception ex) {
                Logger.getLogger(ReflectController.class.getName()).log(Level.SEVERE, null, ex);
            }
            hpg.getChildren().add(hot);
            hpg.getChildren().add(hit);
        }

    }

这里的 newObject 是稍后要通过 hibernate 插入到数据库中的对象。我的问题是这样的:

如何将该对象中的某个字段分配给当前正在创建的文本输入。到目前为止,如果我像上面那样将方法放入值中,它只会在该输入的 value 属性中打印出方法。我想要的是,当提交此表单时,将该文本框中的值分配给具有该名称的属性。

4

3 回答 3

2

在 JSF 中,将输入组件绑定到属性是使用 EL 表达式完成的。你可以像 Steve 展示的那样以编程方式创建一个,但这种语法真的很丑陋。在相关的说明中,组件树的编程操作是使用 JSF 的一种相当非正统的方式。解决您的要求的正统方法是:

<ui:repeat var="prop" value="#{genericEditorBean.propertyNames}">
    <h:outputLabel value="#{prop}" for="input"/>
    <h:inputText id="input" value="#{genericEditorBean.object[prop]}"/>
</ui:repeat>

在哪里

public List<String> getPropertyNames() {
    List<String> propertyNames = new ArrayList<>();
    BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
    for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
        propertyNames.add(pd.getName());
    }
    return propertyNames;
}

(当Java API为此目的提供一个类时,确实没有理由重新实现对Java Bean属性的扫描。与您自己开发的版本不同,这还将处理从超类继承的属性......)

于 2012-08-15T23:14:25.200 回答
2

我曾经使用一个名为MetaWidget的开源库来执行此操作。

那是几年前的事了,但它运行良好且易于设置。

看起来该项目仍然处于活动状态:

于 2012-08-15T23:35:05.283 回答
2

我可以给你一个部分答案 - 你需要动态创建一个 ValueExpression

    Application app = FacesContext.getCurrentInstance().getApplication();
    hit.setValueExpression("value", app.getExpressionFactory().createValueExpression(FacesContext.getCurrentInstance().getELContext(), "#{bean.item}", Item.class));

困难的部分将是创建实际映射到对象值中的字段的 valueExpression。这需要更多的思考,但您肯定需要动态 valueExpression。如所写,这将导致执行您的 bean 的 setItem(); 方法,其参数类型为 Item。您将需要一些更复杂的东西。

于 2012-08-15T21:23:51.810 回答