5

オブジェクトタイプが何であるかを知らなくても、休止状態のデータベースにデータを挿入するための単純なクラッドフォームを作成しようとしています。最終的な目標は、データベース内のテーブルごとに1つの挿入フォームのみを持つことです。これまでのところ、現在のオブジェクトにあるメソッドを取得し、セットされたメソッドがあるかどうかを確認し、セットがあるすべてのフィールドにテキスト入力を作成します。

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は、後で休止状態でデータベースに挿入されるオブジェクトです。私の問題はこれです:

そのオブジェクトから現在作成されているテキスト入力に特定のフィールドを割り当てるにはどうすればよいですか。これまでのところ、上記のようにメソッドを値に入れると、その入力のvalue属性にメソッドが出力されます。私が欲しいのは、このフォームが送信されたときに、そのテキストボックスの値をその名前のプロパティに割り当てるためです。

4

3 に答える 3

2

私はあなたに部分的な答えを与えることができます-あなたは動的にValueExpressionを作成する必要があります

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

難しい部分は、オブジェクトの値内のフィールドに実際にマップされるvalueExpressionを作成することです。それにはもっと多くのことを考える必要がありますが、確かに動的なvalueExpressionが必要になります。記述されているように、これにより、タイプItemのパラメーターを使用してBeanのsetItem();メソッドが実行されます。もう少し複雑なものが必要になります。

于 2012-08-15T21:23:51.810 に答える
2

JSFでは、入力コンポーネントをプロパティにバインドするには、EL式を使用します。スティーブが示すようにプログラムで作成できますが、その構文は本当に醜いです。関連する注記として、コンポーネントツリーのプログラムによる操作は、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 に答える