2012-08-15 27 views
4

我想創建一個簡單的crud表單來將數據插入到具有hibernate的數據庫中,而不知道對象類型是什麼。最終目標是對數據庫中的每個表只有一個插入表單。到目前爲止,我得到了當前對象所擁有的方法,請檢查它是否有任何set方法,併爲每個有set的字段創建一個文本輸入。用java反射動態創建JSF表單

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屬性中輸出方法。我想要的是,當這個表單submited時,用於將該文本框中的值分配給具有該名稱的屬性。

回答

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。你會需要一些更復雜的東西。

1

在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 Bean的屬性時,在Java API提供了一個類是非常與您的自制版本不同,這也將處理從超類繼承的屬性......)