Erreur de Validation: la valeur N'est pas valide

j'ai un problème avec un p:selectOneMenu, peu importe ce que je fais, Je ne peux pas obtenir JSF pour appeler le setter sur l'entité JPA. La validation JSF échoue avec ce message:

formulaire:emplacement: Erreur de Validation: la Valeur n'est pas valide

j'ai ce travail sur plusieurs autres classe du même type (c'est-à-dire, joindre des classes de table) mais ne peut pas pour la vie de moi obtenir ce travail.

si quelqu'un peut jeter dépannage/débogage des conseils pour ce genre de problème, il serait grandement apprécié.

J'ai vérifié ce qui suit à l'aide des relevés de journal:

  1. Le Conveter est de retour correct, non null valeurs".
  2. Je n'ai pas de validation dans mes entités JPA.
  3. le setter setLocation(Location location) n'est jamais appelé.

C'est l'exemple le plus simple que je puisse faire et cela ne marchera tout simplement pas:

<h:body>
    <h:form id="form">
        <p:messages id="messages" autoUpdate="true" />
        <p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
            <p:ajax event="change" update=":form:lblLocation"/>
            <f:selectItems value="#{locationStockList.locationSelection}"/>
        </p:selectOneMenu>
    </h:form>
</h:body>

convertisseur:

@FacesConverter(forClass=Location.class, value="locationConverter")
public class LocationConverter implements Converter, Serializable {
    private static final Logger logger = Logger.getLogger(LocationConverter.class.getName());

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value.isEmpty())
            return null;
        try {
            Long id = Long.parseLong(value);
            Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id);
            logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location});
            return location;
        } catch (NumberFormatException e) {
            return new Location();
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null || value.toString().isEmpty() || !(value instanceof Location))
            return "";
        return String.valueOf(((Location) value).getId());
    }    
}

sortie Console:

// Getter method
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0] 
// Session Bean
INFO: Finding ejb.locations.Location with id=3 
// Session Bean
INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3] 
// Converter
SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3] 
// Getter method -> Where did my selected Location go ??
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0] 
68
demandé sur BalusC 2012-01-30 23:13:10

3 réponses

la Validation échoue avec le message "la forme:emplacement: Erreur de Validation: la Valeur n'est pas valide",

cette erreur se résume au fait que l'élément sélectionné ne correspond à aucune des valeurs disponibles de l'élément sélectionné spécifiées par une étiquette imbriquée <f:selectItem(s)> pendant le traitement de la demande de soumission de formulaire.

dans le cadre de la protection contre les demandes trafiquées/piratées, JSF disponible sélectionnez les valeurs de l'élément et testez si selectedItem.equals(availableItem) renvoie true pour au moins une valeur de l'élément disponible. Si aucune valeur d'article ne correspond, alors vous obtiendrez exactement cette erreur de validation.

ce processus est sous les couvertures essentiellement comme ci-dessous, où bean.getAvailableItems() représente fictionnellement la liste complète des éléments disponibles sélectionner comme défini par <f:selectItem(s)> :

String submittedValue = request.getParameter(component.getClientId());
Converter converter = component.getConverter();
Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue;

boolean valid = false;

for (Object availableItem : bean.getAvailableItems()) {
    if (selectedItem.equals(availableItem)) {
        valid = true;
        break;
    }
}

if (!valid) {
    throw new ValidatorException("Validation Error: Value is not valid");
}

Donc, basé sur la logique ci-dessus, ce problème peut logiquement avoir au moins les causes suivantes:

  1. L'élément sélectionné est manquant dans la liste des éléments disponibles.
  2. la méthode equals() de la classe représentant l'élément sélectionné est manquante ou cassée.
  3. si une coutume Converter est impliquée, alors elle a retourné le mauvais objet dans getAsObject() . Peut-être même null .

pour le résoudre:

  1. veiller à ce que la même liste soit conservée lors de la requête suivante, en particulier dans le cas de plusieurs menus en cascade. Faire le haricot @ViewScoped au lieu de @RequestScoped devrait le corriger dans la plupart des cas. Assurez-vous également que vous n'effectuez pas la logique d'affaires dans la méthode getter de <f:selectItem(s)> , mais plutôt dans @PostConstruct ou une méthode d'action event (listener). Si vous comptez sur des paramètres de requête spécifiques, alors vous devez les stocker explicitement dans le @ViewScoped , ou de les transmettre à nouveau sur des demandes ultérieures par exemple <f:param> . Voir aussi comment choisir le bon Bean scope?
  2. S'assurer que la méthode equals() est appliquée correctement. Cela est déjà fait correctement sur les types Java standard tels que java.lang.String , java.lang.Number , etc, mais pas nécessairement sur les objets/fèves/entités personnalisés. Voir aussi bonne façon de mettre en œuvre équivaut à un contrat . Dans le cas où vous êtes déjà en utilisant String , assurez-vous que le codage de caractères de la requête est configuré correctement. S'il contient des caractères spéciaux et que JSF est configuré pour rendre la sortie UTF-8 mais interprète l'entrée comme par exemple ISO-8859-1, alors il échouera. Voir aussi a. O. Unicode input retrieved via PrimeFaces components input become corrupted .
  3. déboguer / enregistrer les actions de votre coutume Converter et le corriger en conséquence. Pour les directives, voir aussi Valeur de paramètre D'erreur de Conversion pour 'convertisseur null ' dans le cas où vous utilisez java.util.Date comme articles disponibles avec <f:convertDateTime> , assurez-vous que vous n'oubliez pas la partie temps plein dans le modèle. Voir aussi "erreur de Validation: la valeur n'est pas valide" erreur de f:datetimeConverter .

voir aussi:


si n'importe qui peut jeter quelques conseils de dépannage/débogage pour ce genre de problème, il serait grandement apprécié.

il suffit de demander un question claire et concrète. Ne posez pas trop de questions générales ;)

125
répondu BalusC 2017-05-23 12:34:22

dans mon cas, j'ai oublié d'implémenter une méthode get/set correcte. Cela s'est produit parce que j'ai changé beaucoup d'attributs tout au long du développement.

sans une méthode get appropriée, JSF ne peut pas récupérer votre article sélectionné, et se passe ce que BalusC a dit au point 1 de sa réponse:

1 . L'élément sélectionné est manquant dans la liste des éléments disponibles. Cela peut se produire si la liste des articles disponibles est servie par une demande scoped bean qui n'est pas correctement réinitialisé sur demande ultérieure, ou fait incorrectement le travail d'affaires à l'intérieur d'une méthode getter qui lui fait retourner une liste différente d'une certaine manière.

2
répondu Henrique Liberato 2015-02-12 15:18:15

il peut s'agir d'un problème de Convertisseur ou d'un problème DTO. Essayez de résoudre ceci, en ajoutant les méthodes hashCode() et equals() dans votre DTO objet; dans le scénario ci-dessus vous pouvez générer ces méthodes dans la classe d'objet Location qui indique comme 'DTO' ici.

exemple:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (int) (id ^ (id >>> 32));
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Location other = (Location) obj;
    if (id != other.id)
        return false;
    return true;
}
  • veuillez noter que l'exemple ci-dessus est pour un " id "de type "long".
0
répondu Rizla Shareefdeen 2018-08-16 06:00:35