|
Validierung mit JSR303 - aus Architektensichtvon M.JergerDas Problem: RedundanzIn dem Umfeld der Validierung besteht das Hauptproblem darin,
dass Validierung an sehr vielen Stellen benötigt wird. Benötigt zwar auf
ähnliche Art und Weise aber doch immer mit feinen Unterschieden.
Wieder zurück auf der abstrakten Ebene können wir Metadaten
erkennen, mit denen wir unsere Domainobjekte feiner beschreiben können
(z.B. die Min-/Maxlänge des Titels). Wo hilft der der JSR303?Der JSR303 bietet sowohl in der Ecke der Metadaten als auch an
den Stellen, an denen diese Metadaten verwendet werden alles notwendige
- solange Sie nur Validierung im Sinn haben. Sobald Sie aber über
Validierung hinausgehen und z.B. die Tooltips aus dem obigen Beispiel umsetzen
wollen, werden Sie die unschönen Grenzen des JSR303 kennen lernen. Constraints für DomainObjekte zentral definierenFeld-Constraints können direkt am Feld oder am Getter definiert werden.
public class Page extends AbstractPage {
@NotNull @Size(min=1,max=25)
protected String title;
...
Objekt Constraints werdend entsprechend an der Klasse definiert. Validierung durchführenValidierung durchzuführen ist recht einfach. Mit Set validationResult = validator.validate(page); können Sie das page Object aus dem obigen Beispiel validieren. Validierungsfehler werden soweit möglich zusammen als Set zurückgegeben. Wie Sie auf Validierungsfehler reagieren, kann sich hier nach den unterschiedlichen Umgebungsanforderungen richten. Unterschiedliche GranularitätFür die unterschiedlichen Granularitäten (direkt nach der Eingabe, feldweit, objektweit, aggregatweit) bietet JSR303 zwei unterschiedliche Konzepte an. Zum einen bietet ein Validator unterschiedliche Methoden zur Validierung an:
Als zweites Konzept gibt es sogenannte Validierungsgruppen. Eine Validierungsgruppe erlaubt es Validierungen in einer weiteren Dimension noch feiner zu steuern. So macht es zum Beispiel Sinn, teure Validierungen (Rechenzeit, Speicherplatz) von billigen zu unterscheiden. So können die billigen Validierungen immer, die teuren Validierungen nur beim Speichern und ganz teure Validierungen vielleicht nur einmal nachts überprüft werden.
public interface Cheap {}
public class Page extends AbstractPage {
@NotNull(groups=Cheap.class)
protected String title;
...
validator.validate(page, Cheap.class)
WehrmutstropfenBis zu dieser Stelle ist alles in bester Ordnung. Nun kommen wir aber leider an eine unschöne Ecke. Constraint Annotations haben einen direkten Bezug zu ihrem verwendeten Validator. Damit existiert hier eine Abhängigkeit vom Abstrakten (Metadaten) zum Konkreten (Validator), was sehr bedauerlich ist.
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=OnlyAllowedCharacterValidator.class)
public @interface OnlyAllowedCharacter {...}
Denn Sie können so niemals die eigentlich nützlichen Metadaten ohne Ihre Implementierung - die konkreten Validatoren - verwenden. Das Validierungspunkt-Konzept mit AspectJWenn Sie in Ihrem System solche Regeln wie "Factories erzeugen
nur valide Objekte" oder "Das Repository speichert nur valide Objekte"
verwenden, weiß jeder Entwickler in ihrem Team, wann z.B. ein NullCheck notwendig
ist und wann nicht.
public aspect ValidateableAspect {
static Validator validator = AlmostCmsConfiguration.getInstance().validator();
public boolean Validateable.isValid() {
return validate().isEmpty();
}
public Set<ConstraintViolation<Validateable>> Validateable.validate() {
Validateable instance = this;
return validator.validate(instance);
}
pointcut validateableCreation() :
execution (Validateable+ Factory+.*(..));
after() returning(Validateable v) : validateableCreation() {
Set<ConstraintViolation<Validateable>> violations = v.validate();
if(!violations.isEmpty()) {
throw new ValidationException("Invalid Object: " + v +
":" + violations.toString());
}
}
}
Das obige Beispiel erweitert alle Klassen, die das Interface Abenteuer der ersten SchritteAuch wenn es sich lohnt, Validierung nach JSR303 zu verwenden,
sind die ersten Schritte alles andere, als vergnüglich oder einfach. Viel Spaß beim Ausprobieren. |
|
Partner
|
|||||||||||||
|
||||||||||||||||