Introduzione
Abbiamo
già esaminato nei precdenti articoli gli strumenti
messi a disposizione da Struts per effettuare la validazione
dei dati immessi in un form HTML. Il metodo validate() della
classe org.apache.struts.action. ActionForm costituisce il
punto nel quale vengono effettuati i controlli lato server
sui dati immessi. Abbiamo visto come il framework provveda
a rivisualizzare la pagina con i dati immessi in precedenza
affinché si possano correggere gli errori rilevati.
Questo meccanismo che pure allevia di molto il compito dello
sviluppatore presenta alcuni inconvenienti. Il codice di validazione
è spesso duplicato nell'applicazione e un cambiamento
delle regole di validazione implica una modifica ai sorgenti.
Per ovviare a questi problemi è stato sviluppato il
Validator, un componente del Jakarta Common Project che può
essere usato come un add-in di Struts.
Il
Validator
Il
Validator è un framework che fornisce gli strumenti
per effettuare in modo automatico e dichiarativo i controlli
formali sui campi digitati in un form HTML.
Usando il Validator non è necessario scrivere alcun
codice di validazione nel metodo validate() degli ActionForm,
ma è il Validator stesso che fornisce questa funzione
purchè i form bean dell'applicazione estendano uno
degli ActionForm del Validator stesso. .
Il Validator è costiuito da un insieme di classi predisposte
per eseguire tutti i più comuni controlli di validazione
in genere usati nelle applicazioni, ma.esiste anche la possibilità
di creare routine di validazione non fornite dal Validator.
Il Validator inoltre supporta sia la validazione server-side
che quella client-side mediante opportune funzioni JavaScript,
cosa non fornita dal meccanismo standard degli ActionForm
di Struts.
La
configurazione delle routine di validazione da applicare ad
un campo di un form è fatta mediante un file di configurazione
XML, quindi esternamente all'applicazione ed è facilmente
modificabile al mutare delle esigenze applicative. Nel fifle
validator-rules.xml vengono dichiarate tutte le routine di
validazione disponibili, i loro nomi logici e il codice JavScript
corrispondente a ciascuna routine di validazione per l'esecuzione
dei controlli client-side.
Nel file validation.xml si specifica come queste routine vengano
applicate ai vari campi di input dei form dell'applicazione,
ai quali si fa riferimento mediante i nomi dei form beans
dichiarati nello struts-config.xml.
Utilizzare il Validator con Struts significa eseguire i seguenti
step:
-
Abilitare il Validator plug-in
- Configurare
i due file XML appena citati, validator-rules.xml e validation.xml
- Creare
form bean che estendano gli ActionForm del Validator.
Configurare
il Validator per l'uso con Struts
Il Validator viene configurato come un plug-in di Struts.
Per abiliare il Validator bisogna aggiungere nello struts-config.xml
le seguenti righe;
<plug-in
className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,
/WEB-INF/validation.xml"/>
</plug-in>
In
questo modo Struts all'avvio dell'applicazione carica e inizializza
il Validator; si può notare come vengano definiti i
percorsi dei due file XML di configurazione del Validator.
Il validator-rules.xml dichiara le routine di validazione
messe a disposizione dal Validator. Esistono una serie di
routine fornite dalla versione standard del Validator che
coprono la gran parte delle comuni esigenze per ciò
che riguarda i controlli formali da eseguire sui campi di
input di un form. Il file in genere non va quindi modificato
a meno che non si vogliano definire delle proprie routine.
Di seguito è riportato un esempio di una sezione del
file validator-rules.xml riguardante la definizione della
routine di validazione corrispondente al criterio 'required',
ovvero di obbligatorietà di un campo del form. Come
si può vedere ad ogni regola è associato un
nome logico, required in questo caso, è definita la
classe Java che effettua la validazione e il metodo che viene
mandato in esecuzione con i suoi parametri.
Il nome logico della routine sarà usato come riferimento
nel file validation.xml che vedremo.
Inoltre nel tag <javascript> è racchiusa la routine
JavaScript per la validazione client-side.
<form-validation>
<global>
<validator name="required"
classname="org.apache.struts.validator.FieldChecks"
method="validateRequired"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest"
msg="errors.required">
<javascript>
<![CDATA[
function validateRequired(form) {
var isValid = true;
var focusField = null;
var i = 0;
var fields = new Array();
oRequired = new required();
for (x in oRequired) {
var field = form[oRequired[x][0]];
if (field.type == 'text' ||
field.type == 'textarea' ||
field.type == 'file' ||
field.type == 'select-one' ||
field.type == 'radio' ||
field.type == 'password') {
var value = '';
// get field's value
if (field.type == "select-one") {
var si = field.selectedIndex;
if (si >= 0) {
value = field.options[si].value;
}
} else {
value = field.value;
}
if (trim(value).length == 0) { {
if (i == 0) {
focusField = field;
}
fields[i++] = oRequired[x][1];
isValid = false;
}
}
}
if (fields.length > 0) {
focusField.focus();
alert(fields.join('\n'));
}
return isValid;
}
// Trim whitespace from left and right sides of s.
function trim(s) {
return s.replace( /^\s*/, "" ).replace( /\s*$/,
"" );
}
]]>
</javascript>
</validator>
</global>
</form-validation>
Come già accennato per utilizzare il Validator i form
bean dell'applicazione non devono estendere la classe ActionForm
standard di Struts ma la classe org.apache.struts.validator.ValidatorForm
che fornisce l'implementazione del metodo validate(). In questo
caso non è più necessario scrivere il codice
di validazione perché è il Validator che lo
fa per noi. La configurazione dei form bean all'interno dello
struts-config.xml è identica a quella fatta in precedenza
utilizzando la classe ActionForm standard di Struts.
Un esempio di form bean e della sua dichiarazione è
il seguente:
import
org.apache.struts.validator.ValidatorForm;
public
class LogonForm extends ValidatorForm {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
<form-beans>
<form-bean name="logonForm"
type="it.prove.LogonForm"/>
</form-beans>
La
classe è simile ad un ActionForm di Struts tranne l'estensione
di una classe diversa. Inoltre in questo caso non bisogna
implementare i metodi reset() e validate() che sono invece
implementati dalla classe ValidatorForm
Il nome dato al form bean nello struts-config.xml è
usato nel validation.xml per far riferimento al form in questione.
Il validation.xml viene usato per dichiarare i controlli che
verranno effettuati sui campi di input di un form dell'applicazione.
In relazione al form definito in precedenza il validation.xml
potrebbe essere fatto come segue:
<!DOCTYPE
form-validation
PUBLIC "-//Apache Software Foundation//
DTD Commons Validator Rules
Configuration 1.0//EN"
"http://jakarta.apache.org/
commons/dtds/validator_1_0.dtd">
<form-validation>
<formset>
<form name="logonForm">
<field property="username"
depends="required">
<arg0 key="label.username"/>
</field>
<field property="password"
depends="required">
<arg0 key="label.password"/>
</field>
</form>
</formset>
</form-validation>
Per ogni form dell'applicazione va definito un elemento <form></form>
in cui l'attributo name corrisponde al nome del form bean
dichiarato nello struts-config.xml. Gli elementi <field></field>
dichiarano i controlli da eseguire per i campi del form. Nell'esempio
si dichiara che i campi username e password sono obbligatori
mediante l'attributo depends.
Per i messaggi di errore associati a ciascuna routine di validazione
il Validator utilizza il file ApplicationResource.properties
di Struts. In questo file vengono definiti i messaggi di errore
associati a ciascun criterio di validazione definito nel validator-rules.xml
:
errors.required={0}
is required.
errors.minlength={0} cannot be less than {1} characters.
errors.maxlength={0} cannot be greater than {2} characters.
errors.invalid={0} is invalid.
errors.byte={0} must be a byte.
errors.short={0} must be a short.
errors.integer={0} must be an integer.
errors.long={0} must be a long.0. errors.float={0} must be
a float.
errors.double={0} must be a double.
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is an invalid e-mail address.
I
messaggi hanno dei segnaposto per renderne variabile il contenuto
a seconda del campo controllato. Il valore che il Validator
sostituisce al segnaposto è fornito nel validation.xml
nella sezione dedicata al form specifico. Nel caso del required
dell'esempio precedente verrà inserita la descrizione
corrispondente alla key="label.password" fornita
nella sezione <arg0></arg0> del field corrispondente.
Validazione
client-side
Il Validator foirnisce anche il supporto alla validazione
client-side dei form dell'applicazione. Le funzioni JavaSctipt
associate ai diversi criteri di validazione sono definite
nel file validator-rules.xml come già visto. Per abilitare
la validazione client-side è sufficiente inserire nelle
pagine JSP dell'applicazione il seguente tag:
<html:javascript formName="logonForm"/>
Il
validator genererà dinamicamente le routine di validazione
per il form specificato nell'attributo formName del tag <html:javascript>.
Nel nostro caso genererà la funzione validateLogonForm()
che effettuerà la validazione del form purchè
la si colleghi al submit dello stesso come segue:
<html:form
action="logonAction" onsubmit="return validateLogonForm
(this)">
Chiaramente
il submit del form non avverrà se i controlli sui campi
non hanno successo.
La validazione JavaScript consente di evitare i round-trip
con il server dovuti a successivi submit del form conseguenti
ad errori di validazione sui campi digitati nel caso in cui
i controlli vengano eseguiti esclusivamente lato server. In
ogni caso comunque il Validator esegue anche i controlli lato-server
una volta che il submit del form viene effettuato. Ciò
garantisce che i controlli formali vengano effettuati anche
nel caso in cui i controlli JavaScript lato client vengano
disattivati, cosa non da poco visto che in genere nelle applicazioni
web che eseguono i controlli formali sui campi lato client
, le validazioni non vengono eseguite anche lato server come
in realtà dovrebbe essere fatto. Ciò conferisce
una maggiore robustezza ed affidabilità all'applicazione
ed è uno dei principali benefici dell'uso del Validaor.
Conclusioni
In questo articolo abbiamo fatto una panomarica generale sul
Validator. Abbiamo tralasciato alcuni aspetti interessanti,
come ad esempio l'uso dei form dinamici, ma si è cercato
di evidenziare gli aspetti fondamentali del Validator ed i
benefici di un suo utilizzo. Utilizzare il Validator nella
scrittura di una applicazione web J2EE è senz'altro
a mio parere un'ottima scelta poiché consente un notevole
risparmio di ripetitivo codice di validazione ed una standardizzazione
degli algoritmi di controllo. Inoltre la possibilità
di configurare esternamente al codice i tipi di controlli
da effettuare sui campi dei form conferisce grande flessibilità
e manutenibilità all'applicazione stessa.
Bibliografia
[1] Chuck Cavaness - "Programming Jakarta Struts",
O'Reilly, 2003
[2] James Goodwill, Richard Hightower - "Professional
Jakarta Struts" - Wrox 2004
[3] Richard Hightower - "Jakarta Struts Live" -
SourceBeat 2004
Alfredo Larotonda, laureato in Ingegneria
Elettronica, lavora da diversi anni nel settore IT. Dal 1999
si occupa di Java ed in particolare dello sviluppo di applicazioni
web J2EE. Dopo diverse esperienze di disegno e sviluppo ora
si occupa in particolare di aspetti architetturali per progetti
rivolti al mercato finanziario ed industriale. E' Web Component
Developer e Business Component Developer certificato SUN per
la piattaforma J2EE e Programmer per la piattaforma Java.
|