Bonjour, c'est Kurata qui joue avec Spring pour la première fois depuis longtemps. Je ne l'ai pas utilisé depuis environ six mois au travail.
Comme le titre l'indique, j'ai noté le contenu suivant.
Je souhaite vérifier la cohérence avec les données de base stockées dans la base de données.
Mettre en place un formulaire de réservation de salle de réunion. Dans le formulaire de réservation de salle de réunion, sélectionnez la salle de réunion à utiliser avec le bouton radio, puis saisissez la date et l'heure d'utilisation et le nombre de personnes. Il y a plusieurs salles de réunion, chacune avec une capacité fixe. Si plus que la capacité est entrée, une erreur d'entrée se produira.
Obtenez les informations de la salle de réunion en fonction de l'ID de salle de réunion saisi. Obtenez la capacité à partir des informations de la salle de réunion et déterminez si le nombre d'utilisateurs saisi est inférieur ou égal à la capacité. Si la valeur n'est pas valide, un message de validation sera affiché pour le contrôle du formulaire de capacité.
Nous l'avons nommé SeatingCapacityValid
car il s'agit d'une validation de la capacité.
Selon les spécifications de validation, au moins l'ID de la salle et le nom du champ de capacité doivent être reçus en tant qu'argument de l'annotation.
Chacun doit être déclaré comme méthode.
SeatingCapacityValid.java
@Documented
@Constraint(validatedBy = {SeatingCapacityValidator.class}) //Spécifiez une classe qui implémente la logique de validation.
@Target(ElementType.TYPE) //Parce que c'est la validation pour plusieurs attributs du formulaire,Désigné pour être accordé à la classe.
@Retention(RetentionPolicy.RUNTIME)
public @interface SeatingCapacityValid{
//Spécifiez la clé du message à afficher par défaut.
String message() default "{com.example.demo.form.validator.SeatingCapacityValid.message}";
String roomIdProperty(); //Recevoir a spécifié le nom de la propriété où l'ID de chambre saisi est stocké.
String numberOfUsersProperty(); //Recevoir une spécification du nom de la propriété où le nombre d'utilisateurs saisi est stocké.
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
SeatingCapacityValid[] value();
}
}
Implémentez l'interface ConstraintValidator
.
Le premier argument de type est une annotation, qui spécifie la cible annotée (dans ce cas, la classe Form, mais pour la polyvalence, le type Object).
SeatingCapacityValidator.java
public class SeatingCapacityValidator implements ConstraintValidator<SeatingCapacityValid, Object> {
@Autowired
private RoomRepository roomRepository;
private String roomIdProperty;
private String timesProperty;
private String message;
@Override
public void initialize(CommodityTimesValid constraintAnnotation) {
roomIdProperty = constraintAnnotation.roomIdProperty();
numberOfUsersProperty = constraintAnnotation.numberOfUsersProperty();
message = constraintAnnotation.message();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
BeanWrapper beanWrapper = new BeanWrapperImpl(value);
Integer roomId = (Integer)beanWrapper.getPropertyValue(roomIdProperty);
Integer numberOfUsers = (Integer) beanWrapper.getPropertyValue(numberOfUsersProperty);
if (roomId == null || numberOfUsers == null) {
return true;
}
Optional<Room> mayBeRoom = roomRepository.findOne(roomId);
return mayBeRoom.map(room -> {
Integer capacity = room.getCapacity();
if (capacity >= numberOfUsers) {
return true;
//Personnaliser les messages TODO
context
.buildConstraintViolationWithTemplate(message)
.addPropertyNode(numberOfUsersProperty)
.addConstraintViolation();
return false;
}).orElse(true);
}
}
La logique d'affichage des messages est décrite dans la partie de SeatingCapacityValidator.java
écrite comme TODO.
Dans le fichier de propriétés, «{0} est défini comme {1} ou moins, et {1} est ciblé pour afficher le nombre de personnes par salle.
SeatingCapacityValidator.java
public class SeatingCapacityValidator implements ConstraintValidator<SeatingCapacityValid, Object> {
//Omission
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
//Omission
return mayBeRoom.map(room -> {
Integer capacity = room.getCapacity();
if (capacity >= numberOfUsers) {
return true;
}
HibernateConstraintValidatorContext hibernateContext =
context.unwrap(HibernateConstraintValidatorContext.class);
hibernateContext.disableDefaultConstraintViolation();
hibernateContext
.addMessageParameter("1", capacity) //Voici le nombre de personnes dans chaque pièce{1}Mis à.
.buildConstraintViolationWithTemplate(message)
.addPropertyNode(numberOfUsersProperty)
.addConstraintViolation();
return false;
}).orElse(true);
}
}
Lors de la validation à l'aide d'annotations, vous devez être conscient de ce qui suit.
Où l'annotation peut-elle être ajoutée? S'agit-il d'une validation de champ unique ou d'un contrôle de corrélation? Est-il vraiment nécessaire de faire une annotation?
Cette fois, je voulais lier la valeur d'entrée de l'écran à un objet qui la place dans la couche de domaine. J'ai donc créé une annotation pour qu'elle soit évaluée au moment de la liaison.
@ Constraint
.À quelle classe la logique de validation doit-elle être déléguée?
Assurez-vous que les informations nécessaires à la validation proviennent de l'annotation.
Les espaces réservés du modèle de message («{0}» ou «{1}») sont remplacés par les informations qui peuvent être obtenues à partir de l'annotation. «{0}» est le nom du champ, et après «{1}», l'argument de l'annotation.
Pour définir autre chose que ce qui précède, utilisez la méthode ConstraintValidatorContext # unwrap (HibernateConstraintValidatorContext.class)
pour convertir en la classe HibernateConstraintValidatorContext, puis définissez la chaîne de caractères à afficher.
Le nom de la méthode à utiliser | Notation d'espace réservé |
---|---|
addMessageParameter(String s, Object o) | {s} |
addExpressionVariable(String s, Object o) | ${s} |
Il y a de nombreuses parties que je n'ai pas écrites sur les prérequis, donc je pense que je vais l'organiser lorsque tout le code sera publié.