2011-07-08 11 views
2

注釈付きBeanから動的フォームを生成します。同じBeanには、Hibernate Validatorを使用して検証のための注釈が付けられます。 フォームは正しくレンダリングされますが、フォームが送信されると検証ステップは実行されません。同じフォームをjsfタグで記述すると、検証が正しく機能します。JSF 2動的フォームとBeanの検証JSR 303

フォームページ:

:EntityBeanの

public UIComponent getDynamicForm() { 
    FacesContext ctx = FacesContext.getCurrentInstance(); 
    Application app = ctx.getApplication(); 
    HtmlPanelGrid panel = (HtmlPanelGrid) app.createComponent(HtmlPanelGrid.COMPONENT_TYPE); 
    panel.setColumns(2); 

    Class currentClass = super.entityClass; 
    while(!currentClass.equals(Object.class)) { 
     Field fields[] = currentClass.getDeclaredFields(); 
     for(Field field: fields) { 
      Annotation id = field.getAnnotation(Id.class); 
      Annotation embeddedId = field.getAnnotation(EmbeddedId.class); 
      OneToMany oneToMany = field.getAnnotation(OneToMany.class); 
      ManyToMany manyToMany = field.getAnnotation(ManyToMany.class); 
      Transient transientTag = field.getAnnotation(Transient.class); 
      Temporal temporal = field.getAnnotation(Temporal.class); 



      if(id == null && embeddedId == null && oneToMany == null && manyToMany == null && transientTag == null) { 
       int modifiers=field.getModifiers(); 
       if(!Modifier.isStatic(modifiers)) { 
        HtmlOutputLabel label = (HtmlOutputLabel) app.createComponent(HtmlOutputLabel.COMPONENT_TYPE); 

        String name = field.getName(); 
        Class clazz = field.getType(); 

        panel.getChildren().add(label); 
        label.setFor(name); 
        label.setValue(StringUtil.capitalize(name)+":"); 

        String expression = "#{__g4cController.entity."+name+"}"; 
        ValueExpression valueExpression = app.getExpressionFactory() 
          .createValueExpression(ctx.getELContext(), 
            expression, 
            clazz); 

        ManyToOne manyToOne = field.getAnnotation(ManyToOne.class); 
        if(manyToOne != null) { 
         HtmlSelectOneMenu input = (HtmlSelectOneMenu) app.createComponent(HtmlSelectOneMenu.COMPONENT_TYPE); 
         input.setId(name); 
         input.setValueExpression("value", valueExpression); 
         input.setLabel(name); 

         UISelectItems items = (UISelectItems) app.createComponent(UISelectItems.COMPONENT_TYPE); 
         input.getChildren().add(items); 
         String manyToOneClassName = field.getType().getSimpleName().toLowerCase(); 
         String itemsExpression = "#{"+manyToOneClassName+".entityListSelectOne}"; 
         ValueExpression itemsValueExpression = app.getExpressionFactory() 
           .createValueExpression(ctx.getELContext(), 
             itemsExpression, 
            SelectItem[].class); 
         items.setValueExpression("value", itemsValueExpression); 
         panel.getChildren().add(input); 
        } else { 
         if(temporal != null) { 
          if(temporal.value().equals(TemporalType.DATE)) { 
           UICalendar input = (UICalendar) app.createComponent(UICalendar.COMPONENT_TYPE); 
           input.setId(name); 
           input.setValueExpression("value", valueExpression); 
           input.setDatePattern("dd/MM/yyyy"); 
           //input.setConverter(new DateConverter()); 
           panel.getChildren().add(input); 
          } 
         } else { 
          HtmlInputText input = (HtmlInputText) app.createComponent(HtmlInputText.COMPONENT_TYPE); 
          input.setId(name); 
          input.setValueExpression("value", valueExpression); 
          input.setLabel(name); 
          input.setSize(50); 
          input.setMaxlength(255); 
          panel.getChildren().add(input); 
         } 

        } 
       } 
      } 
     } 
     currentClass = currentClass.getSuperclass(); 
    } 
    return panel; 
} 

AエンティティBeanの例から始まるフォームを生成

<body> 

    <ui:composition template="/template/basetheme_one_col.xhtml"> 
     <ui:define name="title">#{__g4cController.entityClassName}</ui:define> 

     <ui:define name="main_area"> 

      <h2>#{__g4cController.entityClassName}</h2> 
      <br /> 
      <div id="briciole_pane"> 
       <h:form id="briciole_pane_form" styleClass="form"> 
        <h:commandLink action="home" value="Home" /> 
        <h:outputText value="/" /> 
        Modifica #{__g4cController.entityClassName} 
       </h:form> 
      </div> 
      <br /> 


      <h:form id="edit_record" styleClass="myForm"> 
       <rich:calendar rendered="false" /> 
       <h4>Modifica #{__g4cController.entityClassName}</h4> 

       <h:messages errorClass="error_msg" layout="list" globalOnly="false" /> 
       <br /> 

       <h:panelGrid binding="#{__g4cController.dynamicForm}" /> 


       <div class="box_bottoni"> 
        <div class="box_bottone_azzurro"> 
         <h:commandLink action="#{__g4cController.edit}" value="Salva Modifiche"> 
          <f:param name="cruddao.objectKey" value="#{g4c:getXmlFromObject(__g4cController.entity.id)}" /> 
         </h:commandLink> 
        </div> 
        <h:commandLink action="#{__g4cController.listSetup}" styleClass="link_annulla_rosso" 
            value="Annulla e torna a lista #{__g4cController.entityClassName}" immediate="true" /> 
        <div class="clear"></div> 
       </div> 


      </h:form> 

     </ui:define> 
    </ui:composition> 
</body> 

コード

@Entity 

パブリッククラスIstitutoはSerializableを実装しています、IBaseEntity { private static final long serialVersionUID = 1L;

@Id 
@SequenceGenerator(name="IstitutoGenerator", sequenceName="ISTITUTO_SEQ", allocationSize=1) 
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="IstitutoGenerator") 
@Column(name="ID_ISTITUTO") 
private int idIstituto; 

@NotNull 
private String nome; 

@NotNull 
private String indirizzo; 

@NotNull 
private String comune; 

@NotNull 
@Pattern(regexp="[0-9][0-9][0-9][0-9][0-9]", message="Il CAP deve essere composto da 5 numeri") 
private String cap; 

@OneToMany(mappedBy="istituto") 
private Set<Classe> classes; 

public Istituto() { 
} 

public int getIdIstituto() { 
    return this.idIstituto; 
} 

public void setIdIstituto(int idIstituto) { 
    this.idIstituto = idIstituto; 
} 

public String getCap() { 
    return this.cap; 
} 

public void setCap(String cap) { 
    this.cap = cap; 
} 

public String getComune() { 
    return this.comune; 
} 

public void setComune(String comune) { 
    this.comune = comune; 
} 

public String getIndirizzo() { 
    return this.indirizzo; 
} 

public void setIndirizzo(String indirizzo) { 
    this.indirizzo = indirizzo; 
} 

public String getNome() { 
    return this.nome; 
} 

public void setNome(String nome) { 
    this.nome = nome; 
} 

public Set<Classe> getClasses() { 
    return this.classes; 
} 

public void setClasses(Set<Classe> classes) { 
    this.classes = classes; 
} 

@Override 
public Integer getId() { 
    return this.getIdIstituto(); 
} 

@Override 
public int hashCode() { 
    int hash = 0; 
    hash += this.getIdIstituto(); 
    return hash; 
} 

@Override 
public boolean equals(Object object) { 
    if (!(object instanceof Istituto)) { 
     return false; 
    } 
    Istituto other = (Istituto) object; 
    if (this.getIdIstituto() != other.getIdIstituto()) { 
     return false; 
    } 

    return true; 
} 

@Override 
public String toString() { 
    return this.getNome(); 
} 

}

答えて

4

あなたが入力コンポーネントにjavax.faces.validator.BeanValidatorのインスタンスを追加する必要があります。

input.addValidator(new BeanValidator()); 

理由は、デフォルトのバリデータ(BeanValidatorを1として登録されている)は、タグの実行中に追加されていることです:http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-635

関連する問題