Java Bean Validation des contraintes (de JSR303) impliquant des relations entre plusieurs propriétés de haricots
-
19-09-2019 - |
Question
Dire que j'ai simple haricot java suivant:
class MyBean {
private Date startDate;
private Date endDate;
//setter, getters etc...
}
Y at-il un mécanisme JSR 303 pour créer un validateur personnalisé qui valide la contrainte que startDate doit être avant endDate?
Il me semble être un cas d'utilisation commune, mais je ne peux pas trouver des exemples de ce genre de multiples contraintes de relationsship de propriété.
La solution
Je peux penser à quelques choses à essayer.
Vous pouvez créer un Constraint
avec une cible de type lui-même avec un validateur approprié:
@ValidateDateRange(start="startDate", end="endDate")
public class MyBean {
Vous pouvez encapsuler une plage de dates dans un type et valider que:
public class DateRange {
private long start;
private long end;
public void setStart(Date start) {
this.start = start.getTime();
}
// etc.
Vous pouvez ajouter une propriété simple qui effectue le contrôle:
public class MyBean {
private Date startDate;
private Date endDate;
@AssertTrue public boolean isValidRange() {
// TODO: null checks
return endDate.compareTo(startDate) >= 0;
}
Autres conseils
Si vous utilisez Hibernate Validator dans la version 4.1 ou vous pouvez ensuite utiliser la @ScriptAssert contrainte ainsi un langage de script ou d'expression pour exprimer ce genre de contrainte. L'utilisation de JavaScript votre exemple ressemblerait à ceci:
@ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
public class CalendarEvent {
private Date startDate;
private Date endDate;
//...
}
Vous pouvez obtenir une syntaxe plus compacte par créer une contrainte personnalisée pour le langage de script de votre choix:
@JexlAssert("_.startDate < _.endDate")
public class CalendarEvent {
private Date startDate;
private Date endDate;
//...
}
La réponse est un niveau de classe validateur. Vous pouvez définir des contraintes personnalisées que vous pouvez placer sur la classe d'entités. Au moment de la validation, vous obtenez passé toute instance dans la méthode isValid (). Vous pouvez ensuite comparer vos deux dates contre l'autre. Voir aussi la mise en veille prolongée Validator documentation .
Comme il n'y a aucun moyen d'accéder à la fève dans un JSR 303 validateur, cela est impossible.
Une solution serait de fournir votre propre ConstraintValidatorContext
et l'étendre avec une référence au bean validons actuellement. Mais je ne suis pas sûr que vous pouvez modifier / remplacer l'usine respective.