Annotations de javax.validation.les contraintes ne fonctionnent pas
Quelle configuration est nécessaire pour utiliser les annotations javax.validation.constraints
@Size
,@NotNull
, etc.? Voici mon code:
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Person {
@NotNull
private String id;
@Size(max = 3)
private String name;
private int age;
public Person(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
}
Quand j'essaie de l'utiliser dans une autre classe, la validation ne fonctionne pas (c'est à dire que l'objet est créé sans erreur):
Person P = new Person(null, "Richard3", 8229));
pourquoi n'applique-t-on pas des contraintes pour id
et <!--6? De quoi dois-je faire?
8 réponses
Pour la JSR-303 bean validation de travailler au Printemps, vous avez besoin de plusieurs choses:
- configuration de l'espace de noms MVC pour les annotations:
<mvc:annotation-driven />
- the JSR-303 spec JAR:
validation-api-1.0.0.GA.jar
(regarde comme vous l'avez déjà) - une implémentation du spec, telle que la Validation Hibernate, qui semble être l'exemple le plus couramment utilisé:
hibernate-validator-4.1.0.Final.jar
- dans le haricot à valider, des annotations de validation, soit à partir du bocal spec, soit à partir du jar implementation (ce que vous avez déjà fait)
- Dans le gestionnaire vous souhaitez valider, d'annoter l'objet que vous souhaitez valider avec
@Valid
, et ensuite inclure unBindingResult
dans la signature de la méthode pour saisir les erreurs.
Exemple:
@RequestMapping("handler.do")
public String myHandler(@Valid @ModelAttribute("form") SomeFormBean myForm, BindingResult result, Model model) {
if(result.hasErrors()) {
...your error handling...
} else {
...your non-error handling....
}
}
Vous devriez utiliser Validator pour vérifier si votre classe est valide.
Person person = ....;
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);
alors, ensemble itératif de violations, vous pouvez trouver des violations.
Vous devrait appeler un validateur sur l'Entité si vous souhaitez valider. Ensuite, vous obtiendrez un ensemble de Forcerviolationexception de contrainte, qui essentiellement show, qui champ/s de votre Entité, il y a une violation de contrainte et quel était exactement ça. Peut-être Pouvez-vous aussi partager une partie du code que vous attendez pour valider votre entité.
une technique souvent utilisée est de faire la validation dans @PrePersist et la transaction de retour en arrière si utilisant des données multiples modifications pendant la transaction ou faire d'autres actions lorsque vous obtenez une exception de validation.
Ton code comme ceci:
@PrePersist
public void prePersist(SomeEntity someEntity){
Validator validator = Validation.buildDefaultValidatorFactory.getValidator();
Set<ConstraintViolation<SomeEntity>> = validator.validate(someEntity);
//do stuff with them, like notify client what was the wrong field, log them, or, if empty, be happy
}
Vous pouvez aussi simplement utiliser des @NonNull
lombok bibliothèque au lieu de cela, au moins pour les @NotNull
scénario. Plus de détails: https://projectlombok.org/api/lombok/NonNull.html
dans mon cas, j'avais une contrainte de classe personnalisée qui n'était pas appelée.
@CustomValidation // not called
public class MyClass {
@Lob
@Column(nullable = false)
private String name;
}
dès que j'ai ajouté une contrainte au niveau du champ à ma classe, que ce soit sur mesure ou standard, la contrainte au niveau de la classe a commencé à fonctionner.
@CustomValidation // now it works. super.
public class MyClass {
@Lob
@Column(nullable = false)
@NotBlank // adding this made @CustomValidation start working
private String name;
}
semble comme comportement buggy pour moi, mais assez facile de travailler autour je suppose
Donc @Valide à l'interface de service ne peut fonctionner que pour cet objet. Si vous avez d'autres validations dans la hiérarchie de L'objet ServiceRequest, alors vous pourriez avoir explicitement déclenché les validations. Donc, c'est comment je l'ai fait:
public class ServiceRequestValidator {
private static Validator validator;
@PostConstruct
public void init(){
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
public static <T> void validate(T t){
Set<ConstraintViolation<T>> errors = validator.validate(t);
if(CollectionUtils.isNotEmpty(errors)){
throw new ConstraintViolationException(errors);
}
}
}
vous devez avoir les annotations suivantes au niveau de l'objet si vous voulez déclencher la validation de cet objet.
@Valid
@NotNull
je suis assez nouveau au printemps donc s'il vous plaît prendre ma réponse avec un grain de sel. Je ne pouvais pas non plus obtenir @NotNull pour travailler quand je l'ai utilisé. J'avais un écran avec des champs d'Entrée, Je ne l'ai pas rempli, et j'ai avancé mon écran (pour une éventuelle économie à un certain DB).
je me creusais le cerveau seulement pour tomber sur @NotBlank aussi bien. Ce fut ma réponse de toute façon. Le champ en question était vide, je suppose qu'il était "" ou une chaîne vide pas null par say. Donc le chèque pour @NotBlank était attraper.
Je ne suis pas sûr que cela vous aidera, mais ça ne peut pas faire de mal d'enquêter sur cette possibilité si vous êtes aussi aux prises avec des @NotNulls qui ne sont pas touchés.
Vous devez ajouter @Valide chaque variable membre, qui était aussi un objet qui contenait des contraintes de validation.