"Erreur de Validation: la valeur N'est pas valide" erreur de f: datetimeConverter

Le code suivant crée deux boutons radio. Chaque option contient une valeur de date qui est convertie avec succès en une étiquette du format "AAAA-MM-JJ". Une fois que je fais une sélection et cliquez sur le bouton suivant, j'obtiens l'erreur suivante "j_idt12:comDateChoice: Erreur de Validation: la Valeur n'est pas valide". Cela semble assez simple, mais quelque chose ne va pas. Pouvez-vous tout de spot?

j'utilise JSF 2.0 dans glassfish.

background bean

public List<SelectItem> getComDateList() {
    List<SelectItem> items = new ArrayList<SelectItem>();
    Calendar cal = GregorianCalendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, 1);
    cal.add(Calendar.MONTH, 1);
    Date nextFirst = cal.getTime();
    cal.add(Calendar.MONTH, 1);
    Date followingFirst = cal.getTime();
    items.add(new SelectItem(nextFirst, new SimpleDateFormat("yyyy-MM-dd").format(nextFirst)));
    items.add(new SelectItem(followingFirst, new SimpleDateFormat("yyyy-MM-dd").format(followingFirst)));
    return items;
}

code JSF

<h:panelGrid columns="2">
                    <h:outputLabel value="#{msg.FinanceCommencementDate}" for="comDateChoice"/>
                    <h:selectOneRadio id="comDateChoice" value="#{signUpBean.current.commencementDate}" layout="pageDirection">
                        <f:convertDateTime type="date" dateStyle="short"/>
                        <f:selectItems  value="#{signUpBean.comDateList}"/>
                    </h:selectOneRadio>
                </h:panelGrid>
3
demandé sur BalusC 2011-03-23 17:23:34

1 réponses

cette erreur se produira si la valeur de l'article sélectionné n'a pas réussi la vérification Object#equals() sur l'une des valeurs disponibles de l'article sélectionné. Cela peut se produire si le getter a retourné une liste différente pendant la phase appliquer les valeurs de la requête du formulaire soumettre la requête qu'il a fait pendant la demande initiale d'afficher le formulaire.

parce que vous reconstruisez la liste dans le getter au lieu de construire une fois dans le constructeur d'une vue scoped bean, le Date les objets recevront un timestamp différent sur chaque appel, il sera de quelques minutes / secondes dans le futur par rapport à la initiale Date objets. Par conséquent, le equals() échouera.

Déplacer cette logique dans le constructeur de la fève et de réécriture de la lecture, de sorte que c'est ce qu'il est censé faire: retourner uniquement les données . Ne pas charger la logique dans un getter. Vous devriez également mettre le haricot dans le champ de vision pour que le constructeur ne recommencez lorsque vous soumettez le formulaire.

@ManagedBean
@ViewScoped
public class SignUpBean {

    private List<SelectItem> comDateList;

    public SignUpBean() {
        comDateList = new ArrayList<SelectItem>();
        // Fill it here.
    }

    public List<SelectItem> getComDateList() {
        return comDateList; // In getters, do nothing else than returning data!
    }

}

Update : le convertisseur est aussi une source potentielle du problème. Vous lui avez demandé de supprimer le temps de rendu de la page HTML. Il utilise donc le temps par défaut lors de la conversion de retour à Date . Soit utiliser

<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS Z" />

ou réinitialiser l'heure et le fuseau horaire sur le Calendar avant:

cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.setTimeZone(TimeZone.getTimeZone("GMT"));

de cette façon, vous pouvez utiliser juste un <f:convertDateTime type="date" />

3
répondu BalusC 2011-03-24 20:16:40