2009-06-25 7 views
6

Ich bin nicht wirklich sicher, ob es eine gute Designentscheidung ist, die Validatoren dazu zu bringen, Befehle basierend auf dem Zustand der Datenbank zu validieren. Wenn ich zum Beispiel eine User-Bean validieren muss, neben der Überprüfung, ob die E-Mail und der Benutzername leer sind, muss ich auch Werte ablehnen, wenn sie bereits verwendet werden. Sollte diese Art von Logik in die Validatoren oder die Serviceobjekte gehen?Sollten Validatoren im Frühjahr auf die Datenbank zugreifen?

Antwort

10

Nun, Ihre Validatoren sind nur Frühlingsbohnen, richtig, damit sie mit den Service-Objekten injiziert werden können, die den Datenzugriff handhaben. Sie können Ihre Validierer Daten aus der Datenbank erhalten, ohne das Design zu kompromittieren.

2

nein, IMHO Validatoren sollten klein sein und side-effect free, damit sie leicht kombiniert werden können. Definitiv sollte ein Validator von Persistenzschicht entkoppelt werden.

+0

Was tun Sie, wenn Sie überprüfen möchten, ob sich eine Referenz auf eine reale Entität bezieht? Sie sollten die Daten nicht ändern, aber manchmal müssen Sie mindestens eine ID-Überprüfung durchführen. –

+0

Ich habe das schon einmal gehört oder gelesen, genau deshalb stelle ich die Frage. Aber ich bin mir nicht sicher, was ich tun soll, wenn ich sie nicht aus einer Datenbank lesen kann (ohne Nebenwirkungen). Ich bin in diesem Thema etwas verwirrt, weil es so aussieht, als würden viele Leute in der Java-Welt deine Meinung teilen, während es in Django und RoR ganz normal ist, die Validierung an die Datenbank zu binden. – Vasil

+0

Und genau wo überprüfen Sie, ob der Benutzername in einem Registrierungsformular bereits vergeben ist? – Janning

1

Ich habe eine von mir und ich bin die Dienstschicht vom Validator Aufruf:

@Service 
public final class StartFormValidator { 
private FacilityService facilityService; 
private AdminService adminService; 

/** 
* Verify that they've selected a facility. Verify that they've selected a 
* valid facility. Verify that they've selected a view and that it's a valid 
* view. 
* 
* @param startForm 
* @param errors 
* @return true if no errors were set 
*/ 
public boolean isValid(final StartForm startForm, final Errors errors) { 
    if (startForm.getFacilityId() == 0) { 
     errors.rejectValue("facilityId", "facilityIdEmpty", 
       "Select a facility."); 
    } 

    if (!this.facilityService.isFacilWaitlistEnabled(startForm 
      .getFacilityId())) { 
     errors.rejectValue("facilityId", "facilityInvalid", 
       "Invalid facility"); 
    } 

    if (StringUtils.isBlank(startForm.getPassword())) { 
     errors.rejectValue("password", "passwordEmpty", 
       "Enter the password."); 

     return (false); 
    } 

    if (!this.adminService.validateAdmin(startForm.getPassword())) 
     errors.rejectValue("password", "passwordInvalid", 
       "Incorrect password"); 

    return (!errors.hasErrors()); 
} 

/** 
* @param _facilityService 
*/ 
@Autowired 
public void setFacilityService(final FacilityService _facilityService) { 
    this.facilityService = _facilityService; 
} 

/** 
* @param _adminService 
*/ 
@Autowired 
public void setAdminService(final AdminService _adminService) { 
    this.adminService = _adminService; 
} 

}

6

Das ist sehr viel abhängen würde, wie Sie die Validierung definieren. Bedenken Sie Folgendes: Sie kaufen etwas und geben Ihre Kreditkartennummer ein. Wenn die Prüfziffer nicht übereinstimmt, ist die Validierung fehlgeschlagen. Es wurde keine Transaktion versucht. Wenn es sich jedoch um eine gültige Kreditkartennummer handelt, die jedoch nicht mit Ihrer Postleitzahl übereinstimmt (DB/Interaktion durch Dritte erforderlich), handelt es sich um einen Zahlungsfehler.

Jetzt betrachten Sie das: Sie geben Ihre Adresse ein, und Sie geben Mastiffica als Ihr Land ein. Warum erlaubte Ihnen das System sogar, diese einzugeben - sie sollten die Schnittstelle nur auf gültige Einträge beschränkt haben (nach der Eingabe war kein DB erforderlich).

Oder Sie geben "fifty" im Betragsfeld Ihres Bankzahlungsbildschirms ein. Warum erlaubt es Buchstaben dort - das schlägt die Validierung fehl (keine Notwendigkeit für DB). Aber Sie geben dann 50 in das Betragsfeld ein, und es stellt sich heraus, dass Sie nicht fünfzig Pfund auf Ihrem Konto haben. Ist das ein Validierungsfehler? Oder ist es eine fehlgeschlagene Transaktion?

Nun haben Sie alle grundlegenden Validierungen (Kreditkartenprüfsumme, Land, Ziffern, Postleitzahl) bestanden und die Transaktion schlägt fehl, weil Ihre Kreditkarte abgelaufen ist. Ist dieser Validierungsfehler oder eine fehlgeschlagene Transaktion?

Sie können sich die Validierung als eine grundlegende Garantie vorstellen, dass Benutzer keine völlig wilden Daten eingeben, oder Sie können sich eine Validierung als "Ich kann diese Transaktion mit den Daten, die ich erhalten habe, abschließen" vorstellen. Ich würde den ersteren persönlich bevorzugen, aber es ist wieder eine Frage der Definition.

Dann ist da noch der Aspekt der ersten Zeile Validierung als Sicherheitsmaßnahme - wilde Daten, die über Ihre Top-UI-Ebene akzeptiert wurde, kann ein Sicherheitsrisiko (SQL-Injektion, zB) sein

1

Wenn Sie wirklich in „MVC glauben "Dann denke ich nicht, dass Sie möchten, dass Ihre Validierer zur Datenbank gehen. Validation ist eine Phase, die die Daten im Wesentlichen aus Sicht der Geschäftslogik validiert.

Die Datenbank muss nicht wissen, wie Validatoren sie verwenden, und Validierer sollten nicht wissen, wie die Datenbank aussieht. Das passt einfach nicht in MVC-Modell. Wenn Sie morgen Daten aus mehreren Quellen haben, würden Sie trotzdem fortfahren und Ihren Validatoren mitteilen, auf welche Quelle sie unter welchen Bedingungen zugreifen soll. Das selbst wird Logik bilden, die nicht einmal req ist. in der Anwendung.

Die Art der Validierung, die Sie suchen, wird als Teil von Geschäftsobjekten aufgenommen, die sicherstellen würden, dass die Serviceobjekte überhaupt aufgerufen werden; Eine solche Kombination gibt es nicht schon.

Service-Objekte sollten auch keine Business-Validierungen enthalten, also weder in Validatoren noch in Service-Objekten. Aber ja, wenn die Anwendung klein genug ist, um sich nicht um zu viele Schichten zu kümmern, ist ein verzerrter Ansatz in Ordnung, aber nur so lange, wie "er als Standard überall eingehalten wird".

Kurz gesagt, ich spüre, dass Federvalidatoren für grundlegende Validierungen und nicht wirklich Business Validierungen gedacht sind.

0

Ich bevorzuge Validierung, die die Datenbank aufgrund der Benutzerfreundlichkeit verwendet.

Beim Absenden eines Registrierungsformulars möchten Sie prüfen, ob der Benutzername syntaktisch korrekt ist und ob dieser Benutzername nicht bereits vergeben ist (DB-Zugriff erforderlich).

Das Formular kann mit allen Fehlern gleichzeitig zurückgegeben werden. Es kann dem Benutzer alle Probleme zeigen. Der Benutzer kann es beheben und das Formular erneut senden.

Ich weiß, dass Sie es schlauer mit Ajax und so weiter machen können, das ist nicht der Punkt.

Ich überprüfe immer alles. Ich überprüfe, ob dieses Formular von der bevorstehenden Transaktion bearbeitet wird. Wenn nicht, erhalte ich eine Ausnahme aufgrund eines gleichzeitigen Zugriffs, der leicht gehandhabt werden kann.

Verwandte Themen