2009-06-25 16 views
6

Non sono sicuro che sia una buona decisione progettuale fare in modo che i validatori convalidino i comandi in base allo stato del database. Per esempio se ho bisogno di convalidare un bean User oltre a controllare se l'email e il nome utente sono vuoti ecc. Devo anche rigettare i valori se sono già usati. Questo tipo di logica dovrebbe andare nei validatori o negli oggetti di servizio?I validatori in primavera dovrebbero accedere al database?

risposta

10

Bene, i vostri validatori sono solo bean di primavera, giusto, quindi possono essere iniettati con gli oggetti di servizio che gestiscono l'accesso ai dati. Puoi chiedere ai tuoi validatori di ottenere dati dal database senza comprometterne la progettazione.

2

no, i validatori IMHO devono essere di dimensioni ridotte e side-effect free per consentirne una facile combinazione. Definitivamente un validatore deve essere disaccoppiato dal livello di persistenza.

+0

Cosa fai quando vuoi verificare che un riferimento si riferisca ad una vera entità? Non dovrebbero modificare i dati, ma a volte è necessario eseguire almeno una verifica di identificazione. –

+0

Ho sentito o letto questo prima, questo è esattamente il motivo per cui sto facendo la domanda. Ma non sono proprio sicuro di cosa dovrei fare se non riesco a renderli in grado di leggere da un database (senza effetti collaterali). Sono un po 'confuso su questo argomento perché sembra che molte persone nel mondo Java condividano la tua opinione, mentre in Django e RoR è perfettamente normale legare la convalida al database. – Vasil

+0

E esattamente dove si controlla se il nome utente in un modulo di registrazione è già stato dato? – Janning

1

ho controllato uno dei miei e sto chiamando il livello di servizio dal validatore:

@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

Questo sarebbe molto dipenderà da come si definisce la convalida. Considera questo: stai acquistando qualcosa e inserisci il numero della tua carta di credito. Se la cifra di controllo non corrisponde, la convalida non è riuscita. Nessuna transazione è stata tentata. Se, tuttavia, è un numero di carta di credito valido, ma non corrisponde al codice postale (è richiesta l'interazione di terze parti/DB), si tratta di un errore di pagamento.

Ora considera questo: stai inserendo il tuo indirizzo e inserisci Mastiffica come nazione. Perché il sistema ti ha persino permesso di entrare in questo - avrebbero dovuto limitare l'interfaccia solo alle voci valide (nessun DB aveva bisogno di inserire post).

Oppure inserisci "cinquanta" nel campo importo della schermata di pagamento bancario. Perché consente le lettere lì - che non convalida la convalida (non c'è bisogno di DB). Ma poi inserisci 50 nel campo importo e risulta che non hai cinquanta sterline nel tuo account. È un errore di convalida? O è una transazione fallita?

Ora, considera di aver superato tutte le convalide di ingresso di base (somma di carta di credito, paese, cifre, codice postale) e la transazione non riesce, perché la tua carta di credito è scaduta. È un errore di convalida o una transazione fallita?

Si può pensare alla convalida come garanzia di base che gli utenti non inseriranno dati completamente selvaggi, o si può pensare alla convalida come "Posso completare questa transazione con i dati che mi sono stati dati". Personalmente preferirei il primo, ma ancora una volta è questione di definizione.

Poi c'è l'aspetto della prima convalida linea come misura di sicurezza - i dati selvaggia che è stata accettata oltre il vostro livello di interfaccia utente in alto può essere un rischio per la sicurezza (SQL injection, ad esempio)

1

Se credi davvero in "MVC "quindi non credo, vorrai che i tuoi validatori vadano nel database. La validazione è una fase che essenzialmente convalida i dati dal punto di vista della logica aziendale.

Il database non deve essere a conoscenza di come i validatori lo utilizzeranno, né i validatori dovrebbero essere a conoscenza del database. Questo non si adatta al modello MVC. Domani se avete dati provenienti da più fonti, continueresti comunque a comunicare ai tuoi validatori quale fonte specifica dovrebbe accedere a quali condizioni. Quello stesso costituirà una logica che non è nemmeno richiesta. in applicazione.

Il tipo di convalida che si sta cercando sarà preso come parte degli oggetti di business che garantirebbe che prima che gli oggetti di servizio siano anche chiamati; tale combinazione non esiste già.

oggetti Servizio dovrebbe anche non contenere le convalide di business, in modo da non appartiene a validatori né negli oggetti di servizio. Ma sì, se l'applicazione è abbastanza piccola da non preoccuparsi di troppi livelli, un approccio distorto va bene, ma solo fino a quando "è seguito come standard in tutto".

In breve, credo che i validatori di molle siano pensati per convalide di base e non per validazioni aziendali.

0

Io preferisco la convalida che utilizza il database a causa dell'usabilità dell'utente finale.

Inviando un modulo di registrazione, si desidera verificare se il nome utente è sintatticamente corretto e se questo nome utente non è già stato fornito (è necessario l'accesso al DB).

Il modulo può restituire tutti gli errori contemporaneamente. Può mostrare all'utente tutti i problemi. L'utente può ripararlo e inviare di nuovo il modulo.

So che si può fare più intelligente con l'Ajax e così via, non è questo il punto.

Controllo sempre tutto. Controllo se questo modulo verrà gestito dalla transazione in arrivo. In caso contrario, ottengo un'eccezione a causa di un accesso concorrente che può essere gestito facilmente.

Problemi correlati