Hallo, das ist Kurata, die zum ersten Mal seit langer Zeit wieder mit Spring rumgespielt hat. Ich habe es seit ungefähr einem halben Jahr bei der Arbeit nicht mehr benutzt.
Wie der Titel schon sagt, habe ich den folgenden Inhalt notiert.
Ich möchte die Konsistenz mit den in der Datenbank gespeicherten Stammdaten überprüfen.
Implementieren Sie ein Reservierungsformular für Besprechungsräume. Wählen Sie im Reservierungsformular für Besprechungsräume den Besprechungsraum aus, der mit dem Optionsfeld verwendet werden soll, und geben Sie Datum und Uhrzeit der Nutzung sowie die Anzahl der Personen ein. Es gibt mehrere Tagungsräume mit jeweils fester Kapazität. Wenn mehr als die Kapazität eingegeben wird, tritt ein Eingabefehler auf.
Rufen Sie die Besprechungsrauminformationen basierend auf der eingegebenen Besprechungsraum-ID ab. Beziehen Sie die Kapazität aus den Informationen im Besprechungsraum und bestimmen Sie, ob die eingegebene Anzahl von Benutzern kleiner oder gleich der Kapazität ist. Wenn der Wert ungültig ist, wird eine Validierungsnachricht für die Kapazitätsformularsteuerung angezeigt.
Wir haben es "SeatingCapacityValid" genannt, weil es eine Validierung der Kapazität ist. Gemäß den Validierungsspezifikationen müssen mindestens die Raum-ID und der Name des Kapazitätsfelds als Argument für die Anmerkung empfangen werden. Jeder muss als Methode deklariert werden.
SeatingCapacityValid.java
@Documented
@Constraint(validatedBy = {SeatingCapacityValidator.class}) //Geben Sie eine Klasse an, die die Validierungslogik implementiert.
@Target(ElementType.TYPE) //Weil es die Validierung für mehrere Attribute des Formulars ist,Bestimmt, um der Klasse gewährt zu werden.
@Retention(RetentionPolicy.RUNTIME)
public @interface SeatingCapacityValid{
//Geben Sie den Schlüssel der Nachricht an, die standardmäßig angezeigt werden soll.
String message() default "{com.example.demo.form.validator.SeatingCapacityValid.message}";
String roomIdProperty(); //Receive gab den Namen der Unterkunft an, in der die eingegebene Raum-ID gespeichert ist.
String numberOfUsersProperty(); //Erhalten Sie eine Angabe des Namens der Eigenschaft, in der die eingegebene Anzahl von Benutzern gespeichert ist.
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
SeatingCapacityValid[] value();
}
}
Implementieren Sie die Schnittstelle "ConstraintValidator". Das erste Typargument ist eine Annotation, die das annotierte Ziel angibt (in diesem Fall die Form-Klasse, aus Gründen der Vielseitigkeit jedoch den Objekttyp).
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;
//Passen Sie TODO-Nachrichten an
context
.buildConstraintViolationWithTemplate(message)
.addPropertyNode(numberOfUsersProperty)
.addConstraintViolation();
return false;
}).orElse(true);
}
}
Die Nachrichtenanzeigelogik wird in dem als TODO geschriebenen Teil von SeatingCapacityValidator.java
beschrieben.
In der Eigenschaftendatei definieren wir `{0} als die Anzahl der Personen unter {1} und das Ziel ist es, die Anzahl der Personen pro Raum in {1} anzuzeigen.
SeatingCapacityValidator.java
public class SeatingCapacityValidator implements ConstraintValidator<SeatingCapacityValid, Object> {
//Unterlassung
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
//Unterlassung
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) //Hier ist die Anzahl der Personen in jedem Raum{1}Einstellen.
.buildConstraintViolationWithTemplate(message)
.addPropertyNode(numberOfUsersProperty)
.addConstraintViolation();
return false;
}).orElse(true);
}
}
Bei der Validierung mithilfe von Anmerkungen sollten Sie Folgendes beachten.
Wo kann die Anmerkung hinzugefügt werden? Handelt es sich um eine Einzelfeldvalidierung oder eine Korrelationsprüfung? Ist es wirklich notwendig, eine Anmerkung zu machen?
Dieses Mal wollte ich den Eingabewert vom Bildschirm an ein Objekt binden, das ihn in die Domänenebene einfügt. Deshalb habe ich eine Anmerkung erstellt, damit sie zum Zeitpunkt der Bindung ausgewertet wird.
An welche Klasse soll die Validierungslogik delegiert werden?
Stellen Sie sicher, dass die für die Validierung erforderlichen Informationen aus der Anmerkung stammen.
Die Platzhalter für Nachrichtenvorlagen ("{0}" oder "{1}") werden durch die Informationen ersetzt, die aus der Anmerkung abgerufen werden können.
{0}
ist der Feldname und nach {1}
das Argument der Annotation.
Verwenden Sie zum Festlegen einer anderen als der oben genannten Methode die Methode "ConstraintValidatorContext # unwrap (HibernateConstraintValidatorContext.class)", um sie in die Klasse "HibernateConstraintValidatorContext" zu konvertieren, und legen Sie dann die anzuzeigende Zeichenfolge fest.
Der Name der zu verwendenden Methode | Platzhalternotation |
---|---|
addMessageParameter(String s, Object o) | {s} |
addExpressionVariable(String s, Object o) | ${s} |
Es gibt viele Teile, die ich nicht über die Voraussetzungen geschrieben habe, daher denke ich, dass ich sie organisieren werde, wenn der gesamte Code veröffentlicht wird.