MokaByte 84 - Aprile 2004 
Sviluppare applicazioni J2EE con Jakarta Struts
IV parte: i componenti della View

di
Alfredo Larotonda
In questo articolo esaminiamo i componenti che costiuiscono la View nell'architettura di Struts. Come già detto negli articoli precedenti, in base al pattern MVC la view è lo strato che fornisce all'utente la visualizzazione dello stato del model; in pratica è l'interfaccia utente dell'applicazione. Anche se la view dell'applicazione può essere realizzata in diversi modi, nel nostro caso, parlando di applicazioni web, ci riferiremo alla tecnologia più diffusa nell'ambito della J2EE per lo strato di view che ovviamente è costiuita dalle Java Server Pages.

La classe ActionForm
In ogni applicazione web la view ha due compiti fondamentali: presentare all'utente i dati frutto dell'elaborazione eseguita e consentire all'utente l'immissione di dati elaborare.
Normalmente in una applicazione J2EE tradizionale i dati da visualizzare sono contenuti negli attributi di un JavaBean memorizzato nell'appropriato scope al quale la pagina fa riferimento.
L'immissione di dati è realizzata mediante un FORM Html contenuto nella pagina JSP e i vari input type che consentono l'invio nella request di dati che saranno reperiti dai componenti del controller e passati allo strato di business logic.
Il reperimento dei dati dalla request, la loro validazione e il popolamento con essi degli oggetti del model è a carico dello sviluppatore che dovrà scrivere codice per reperire i dati dalla request , istanziare un oggetto di una classe opportuna per memorizzarli , validarli e fornirli allo strato di business-logic.
Gli ActionForm di Struts consentono di automatizzare in parte questo compito che è uno dei più frequenti e ripetitivi in una applicazione web J2EE.
Un ActionForm è una classe che estende la org.apache.struts.actions.ActionForm e che viene utilizzata per acquisire i dati da un form HTML e fornirli ad una classe Action.
In pratica il controller di Struts provvede a popolare in automatico gli attributi di un ActionForm associato ad una determinata Action con i dati inviati nella request, associandoli in base alla corrispondenza nome-parametro nome-attributo, e a passare l'istanza dell'ActionForm così valorizzata al metodo execute() della Action stessa.
Gli ActionForm costiuiscono quindi una sorta di buffer nel quale vengono posti i dati digitati in un form HTML, che possono così essere ripresentati facilmente all'utente in caso di errori nella validazione. Allo stesso tempo costiuisce per così dire un 'firewall' per l'applicazione in quanto facilita il controllo dei dati prima che questi vengano passati allo strato di logica.
Gli ActionForm sono del tutto equivalenti a dei JavaBean e possono essere quindi utilizzati per contenere i dati restituiti dallo strato di business logic e da presentare all'utente oltre che a essere usati come classi corrispondenti ad un form Html come il loro nome suggerisce.
Di seguito è riportato il codice di esempio di un ActionForm corrispondente ad un classico form di immissione di username e password:

public class LoginForm extends ActionForm {

  private String password = null;
  private String username = null;

  public String getPassword() {
    return this.password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getUsername() {
    return this.username;
  }

  public void setUsername(String username) {
    this.username = username;
  }
}

Come si vede la struttura è esattamente quella di un JavaBean a parte l'estensione della classe ActionForm. Gli ActionForm estendono la org.apache.struts.actions.ActionForm , ed hanno attributi privati e corrispondenti metodi get e set pubblici. In più hanno due metodi particolari: reset() e validate() che ne caratterizzano il comportamento..
Il metodo reset() viene chiamato dal controller dopo che questo ha creato o reperito dallo scope opportuno l'istanza dell'ActionForm. Può quindi essere usato per inizializzare gli attributi del form ad un valore stabilito.
Il metodo validate() viene chiamato dal controller dopo la valorizzazione degli attributi dell'ActionForm qualora nello struts-config.xml sia stato valorizzato a true l'attributo validate del tag <action> nel quale si fa riferimento all'ActionForm in questione (vedi articolo della serie del mese di Marzo 2004).
Nel metodo validate() va inserito il codice per la validazione formale dei dati del form. Ciò garantisce di avere un punto standard nel codice nel quale questa validazione viene effettuata e che i dati che arrivano alla Action siano già stati formalmente validati.

 

Gli ActionErrors
Il metodo validate() di un ActionForm è il punto nel quale viene inserito il codice di validazione formale dei dati immessi dall'utente in un form HTML.
La signature del metodo è la seguente:
public ActionErrors validate(ActionMappings mapping,HttpServletRequest request)
Il tipo di ritorno del metodo è un oggetto della classe ActionErrors che è un contenitore di oggetti della classe
org.apache.struts.action.ActionError
Ogni oggetto della classe ActionError rappresenta un errore verificatosi nella validazione dei dati. Qualora durante la validazione si verifichino degli errori, per ciascuno di essi viene creata una istanza di un oggetto ActionError e aggiunta all'oggetto ActionErrors restituito dal metodo. Se il controller verifica che l'oggetto ActionErrors in uscita al metodo validate() non è nullo, non trasferisce il controllo al metodo execute() della classe Action associata alla richiesta in elaborazione ma bensì alla pagina JSP il cui path è configurato nell'attributo input del tag <action> corrispondente.
Con un opportuno custom tag (<html:errors>) posto nella pagina stessa sarà possibile visualizzare i messaggi di errore associati agli errori verificatisi senza scrittura di codice aggiuntivo.
Il messaggio di errore viene reperito automaticamente dal framework dal resouce bundle dell'applicazione; la chiave del messaggio è fornita nel costruttore dell'oggetto ActionError associato all'errore in questione. Di seguito è riportato l'esempio di un metodo che esegue la validazione della username e della password immessi nel form html associato all'ActionForm visto in precedenza:

public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {

  ActionErrors errors = new ActionErrors();

  if ((username == null) || (username.length() < 1))
    errors.add ("username",new ActionError("errore.username.obbligatorio"));

  if ((password == null) || (password.length() < 1))
    errors.add("password",new ActionError("errore.password.obbligatoria"));

  return errors;
}

Le label errore.username.obbligatorio e errore.password.obbligatorio sono le chiavi alle quali sono associati i messaggi di errore nel resource bundle dell'applicazione.
Con il metodo validate, le classi ActionErrors ed ActionError ed il tag <html:errors> il framework fornisce quindi un automatismo standard per la gestione della validazione dei dati immessi nella view dell'applicazione e per la visualizzazione dei messaggi di errore.

 

Le librerie di custom-tag di Struts
Per la costruzione delle viste dell'applicazione , Struts mette a disposizione alcune librerie di tag che svolgono alcuni dei compiti più frequenti in una pagina JSP. Le librerie di tag sono raggruppate logicamente in base al tipo di funzione svolta e sono:

  • html Tag per la generazione di form HTML che interagiscono con gli ActionForm e degli altri elementi HTML di una pagina JSP
  • bean Tag usati per accedere a proprietà di JavaBeans e per creare istanze di bean
  • logic Tag usati per logica condizionale, iterazioni e controllo di flusso
  • nested Tag che estendono le funzionalità dei tag base

La libreria html comprende una serie di tag che consentono di generare in automatico ed in maniera standard tag html. In particolare per ciò che riguarda i form HTML questi tag sono strettamente collegati alla discussione fatta sugli ActionForm.
Il tag <html:form> è senza dubbio uno dei più comuni in quanto consente di definire un form HTML. Vi sono poi tag per ciascuno degli input type html.
Nell'esempio seguente viene definito un form la cui action è il path "/login". Questo corrisponderà al path configurato in un blocco <action></action> dello struts-config.xml. Il form contiene due input uno di tipo text ed uno di tipo password i cui valori corrispondono agli attributi username e password dell'ActionForm associato al form in questione. Il valore dell'attributo property dei tag <html:text> e <html:password> corrisponde al nome dell'attributo dell'ActionForm associato al form. Ciò significa che il framework valorizzerà in automatico gli attributi username e password dell'ActionForm con i valori corrispondenti immessi nel form. Il tag <html:submit> genera il codice html di un button di tipo submit.

<html:form action="/login" >
<TABLE>
<TR>
<TH>Username:</TH>
<TD><html:text property="username"/></TD>
</TR>
<TR>
<TH>Password:</TH>
<TD><html:password property="password"/></TD>
</TR>
<TR>
<TD><html:submit/></TD>
</TR>
</TABLE>
</html:form>


Nella libreria logic esistono numerosi tag per eseguire logica condizionale quali <logic:empty> <logic:notEmpty> <logic:equal> <logic:notEqual> <logic:greaterThan> ed altri., tag per eseguire iterazioni su array e collection quali <logic:iterate>, e tag per eseguire controllo di flusso come il <logic:redirect>.

Nella libreria bean sono presenti tag per la definizione di variabili di scripting utilizzabili all'interno della pagina quali <bean:define> , tag per la scrittura in output del valore di attributi di un <bean: write> e così via.

Non è questa la sede per una descrizione dettagliata dei vari tag , per la quale si rimanda comunque alla documentazione ufficiale del framework alla pagina:
http://jakarta.apache.org/struts/userGuide/

Va piuttosto precisato che l'utilizzo dei custom tag nelle pagine JSP è altamente consigliato per evitare il proliferare di scriptlet Java nelle pagine e per rendere standard la scrittura delle stesse.
E' molto importante inoltre osservare che alcuni dei tag forniti nelle librerie di Struts si sovrappongono per la loro funzione con i tag presenti nelle JSTL (Java Standard Tag Library) introdotte di recente nella J2EE.
In particolare i tag della libreria logic di Struts trovano corrispondenza in molti dei tag della libreria core delle JSTL. L'indicazione è di usare sempre questi ultimi in quanto sono già lo standard per la scrittura delle pagine JSP e sicuramente verranno utilizzati nelle versioni future.
Probabilmente la libreria di tag di Struts che avrà ancora largo utilizzo è la html almeno finchè la tecnologia delle Java Server Faces non si sarà diffusa ed affermata.


Conclusioni
In questo articolo abbiamo esaminato gli elementi fondamentali della View di Struts. ActionForm , ActionErrors e librerie di tag forniscono gli strumenti essenziali per velocizzare e standardizzare la scrittura delle viste di una web application J2EE. Le potenzialità degli elementi di Struts appena desritti vanno ben oltre l'esposizione ora fatta, che aveva piuttosto l'obiettivo di offrire una breve panomarica degli elementi messi a disposizione dal framework.

 

Bibliografia
[1] Chuck Cavaness - "Programming Jakarta Struts", O'Reilly, 2003
[2] Rod Johnson - "J2EE Design and Development", Wrox, 2002
[3] James Goodwill, Richard Hightower - Professional Jakarta Struts" - Wrox 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 certificato SUN per la piattaforma J2EE e Programmer per la piattaforma Java.

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it