HTML Guida Struts

42
Guida Apache Struts 1

Transcript of HTML Guida Struts

Page 1: HTML Guida Struts

Guida Apache Struts

1

Page 2: HTML Guida Struts

Indice generaleIntroduzione.....................................................................................................................................4Perché usare Struts...........................................................................................................................4Il design pattern MVC.....................................................................................................................4Componenti e gestione delle richieste in Struts...............................................................................5Il ciclo di vita delle richieste............................................................................................................6Creare un progetto Struts con Eclipse..............................................................................................7Struttura di una semplice applicazione............................................................................................7Il deployment descriptor per Struts..................................................................................................9Configurare la ActionServlet.........................................................................................................10Il mapping delle servlet..................................................................................................................11La taglib.........................................................................................................................................11Pagina di benvenuto ed errori........................................................................................................11Il file di configurazione 'struts-config.xml'....................................................................................11global-forwards..............................................................................................................................12form-beans.....................................................................................................................................13action-mappings.............................................................................................................................13message-resources.........................................................................................................................14plug-in............................................................................................................................................14File di configurazione multipli......................................................................................................15Hello World con Struts...................................................................................................................15Regole e consigli per scrivere applicazioni con Struts..................................................................17Processo di sviluppo......................................................................................................................18Scrivere il markup solo nelle viste.................................................................................................18Tutte le Action finiscono con il .do................................................................................................18Sui jar.............................................................................................................................................18Test e configurazione.....................................................................................................................19ActionServlet.................................................................................................................................19La classe ActionServlet e il RequestProcessor..............................................................................19Configurare l'ActionServlet...........................................................................................................20Le Action........................................................................................................................................21Creare una Action..........................................................................................................................21Il metodo execute()........................................................................................................................22

Azioni HTTP e Custom.............................................................................................................22ActionForward...............................................................................................................................22Configurazione della classe Action................................................................................................23DispatchAction..............................................................................................................................24LookupDispatchAction..................................................................................................................26Forward Action..............................................................................................................................29Esempio.........................................................................................................................................29Link a forward globali...................................................................................................................30Forward Attribute vs. ForwardAction............................................................................................31Forward per accesso Legacy..........................................................................................................31MappingDispatchAction e altre Action già pronte........................................................................33MappingDispatchAction................................................................................................................33BaseAction.....................................................................................................................................34IncludeAction.................................................................................................................................34Il RequestProcessor........................................................................................................................34I Plugin...........................................................................................................................................36

2

Page 3: HTML Guida Struts

init()...............................................................................................................................................36destroy().........................................................................................................................................36Creare un Plugin............................................................................................................................37Le taglib di struts...........................................................................................................................38Jsp Custom Tag..............................................................................................................................38Utilizzare una taglib.......................................................................................................................39La HTML taglib.............................................................................................................................39Tag generici per la formattazione e la navigazione.......................................................................39

Il tag <html:html>.....................................................................................................................40Tag per i form................................................................................................................................40

Il tag <html:form>.....................................................................................................................40Gli eventi JavaScript......................................................................................................................41Bean taglib e gestione dei messaggi..............................................................................................41

Bean taglib e gestione dei messaggi...................................................................................................41Il tag <bean:message>: la gestione dei messaggi..........................................................................41

3

Page 4: HTML Guida Struts

Introduzione

Apache Struts è un progetto open source sponsorizzato dalla Apache Software Foundation ed è un'implementazione Java server-side del design pattern MVC (Model View Controller).

Il progetto Struts è nato con l'intenzione di implementare un framework open-source per la creazione di applicazioni Web che permettesse la separazione del livello di presentazione e che fosse, allo stesso tempo, astratto dai vari livelli di dati e dalle transazioni.

Nato nel 2000 per opera di Craig R. McClanahan (http://blogs.sun.com/craigmcc/), la popolarità del framework è cresciuta enormemente nel corso degli ultimi anni. Dopo il rilascio di Struts 1.1, nel giugno 2003, Struts è diventato uno degli scenari più importanti per lo sviluppo di complesse applicazioni web basate su JSP.

Nel 2008 nasce Struts 2, che si differenzia parecchio dalla prima versione: questa release non segue infatti il progetto originale, ma è una evoluzione di WebWork (http://www.opensymphony.com/webwork/), il framework open source, parte del progetto OpenSymphony. Per questo motivo la migrazione tra la versione 1 e la versione 2 non è semplice. In questa guida ci occuperemo della versione 1 del progetto e analizzeremo la versione 2 per differenze con la prima.

Perché usare StrutsQuesto framework semplifica notevolmente la vita di un programmatore, sia in fase di sviluppo, che di revisione e di configurazione delle proprie applicazioni.

L'utilizzo di Struts supporta vantaggi significativi in termini del progetto:

• Modularità e Riusabilità: i diversi ruoli dell'applicazione sono affidati a diversi componenti. Ció consente di sviluppare codice modulare e più facilmente riutilizzabile

• Manutenibilità: l'applicazione è costituita da livelli logici ben distinti. Una modifica in uno dei livelli non comporta modifiche negli altri

• Rapidità di sviluppo: è possibile sviluppare in parallelo le varie parti dell'applicazione, logica di business e di view

Il design pattern MVCIniziamo esaminando le 3 componenti alla base del design pattern MVC:

Componente Descrizione

ModelRappresenta i dati, tipicamente persistenti su database, attraverso oggetti, questa rappresentazione ci permette di manipolare e il modello dei dati in modo semplificato

ViewÈ lo strato più esterno, quello di presentazione. È qui che definiamo l'interfaccia utente, forniamo una rappresentazione del modello dei dati e riceviamo richieste dall'esterno.

ControllerÈ il componente che contiene la logica di business. Qui gestiamo le interazioni con l'interfaccia, istradiamo le richieste, preleviamo i dati dal Model e stabiliamo quale View dovrà rappresentarli e come.

Figura 1. Model View Controller

4

Page 5: HTML Guida Struts

Questo approccio si preoccupa di separare la responsabilità nelle web application. Una richiesta client viene intercettata dal Controller, attraverso il Model vengono forniti tutti i metodi per accedere ai dati dell'applicazione e quindi per elaborare la risposta e visualizzarla attraverso i componenti View.

Il componente più importante è quindi il Controller ed è la parte fondamentale del framework. La potenza di questo sistema sta, infatti, nella possibilità di scegliere diverse tecnologie per implementare le classi del Model (dal più comune dei DAO a ORM di vario genere come Hibernate (http://java.html.it/articoli/leggi/2421/introduzione-ad-hibernate/)) e il View Engine che si preferisce (JSP, Velocity, etc.).

Nel corso della guida analizzeremo i principali componenti di un'applicazione basata su Struts suddividendoli in componenti model, view e controller; poi passeremo alla configurazione di un applicazione web, descriveremo le funzionalità più importanti offerte da questo framework e infine analizzeremo i concetti principali della nuova versione del progetto.

Componenti e gestione delle richieste in Struts

Struts, come ogni application framework, è un insieme di classi e interfacce che costituiscono lo scheletro per costruire le nostre Web application. In questa lezione iniziamo ad esaminare i componenti fondamentali e il ciclo di vita delle richieste.

Componente Descrizione

ActionServlet

È la servlet di controllo che gestisce tutte le richieste dell'applicazione. Come tutte le servlet estende la classe javax.servlet.http.HttppServlet e quindi implementa tutti i metodi di lifecycle, incluso init(), doGet(), doPost() ed il destroy

struts-config.xmlÈ il cuore di tutta l'applicazione. In questo file XML possiamo definire i vari elementi dell'applicazione e le loro associazioni. Viene letto in fase di start-up dell'applicazione dalla ActionServlet

ActionLe Action sono le classi alle quali le ActionServlet delegal'elaborazione della richiesta

ActionMappingContiene gli oggetti associati ad una Action nello struts-config come ad esempio gli ActionForward

ActionFormSono considerati dei veri contenitori di dati. Fanno riferimento ad uno specifico form e vengono popolati automaticamente dal framework con i dati contenuti nella request HTTP

ActionForward Contengono i path ai quali la servlet di Struts inoltra il flusso in base alla logica

5

Page 6: HTML Guida Struts

dell'applicazione

Custom-tagsSono tag particolari forniti dal framework Struts per assolvere a molti dei più comuni compiti delle pagine JSP

Il ciclo di vita delle richiesteVediamo questi componenti all'opera, esaminando il flusso elaborativo che viene innescato in Struts da una richiesta. Per farlo ci serviamo di un semplice schema:

Figura 1. Flusso Elaborativo di Struts

Come abbiamo detto il controller ha la responsabilità di ricevere l'input da un client, invocare le operazioni necessarie alla logica applicativa e coordinare la vista da restituire al client. In altre parole contiene tutte la logica di business.

Il componente Model fornisce gli oggetti necessari alla logica di business per astrarre la persistenza dei dati. Infine le view rappresentano il modo di interagire dell'applicazione con l'utente sia in fase di richiesta che in fase di risposta.

• I dati per la configurazione sono stati letti dallo struts-config.xml in fase di startup(0

) • il Client invia una richiesta HTTP(1) • la richiesta quale viene ricevuta dalla servlet di Struts che provvede a popolare l'ActionForm

associato alla richiesta con i dati della request(2) e l'ActionMapping associata alla richiesta(4)

• L'Action Servlet delega l'elaborazione dati alla relativa Action(3) passandole in input gli oggetti con request e response HTTP, l'ActionForm e l'ActionMapping precedentemente valorizzati

• La Action compie la logica di business e rende permanente lo stato dell'applicazione colloquiando con il Model(5)

• Al termine dell'elaborazione restituisce alla ActionServlet un ActionForward(6) contenente il path della vista da fornire all'utente

• La Action esegue il forward alla vista specifica nell'ActionForward(7)

6

Page 7: HTML Guida Struts

Questo flusso di operazioni non è completo e in prima battuta sembra un po' confusionario, ma ci sarà utile come mappa, per avere presenti gli attori che vengono coinvolti nella elaborazione delle richieste in un'applicazione.

Creare un progetto Struts con Eclipse

Nelle prime lezioni abbiamo fornito una visone d'insieme del framework, che ci sarà utile per approfondire i concetti nel corso della guida. In questa lezione iniziamo a prendere confidenza con l'infrastruttura di Struts e ci cimentiamo con un primo, semplice, progetto.

Prima di iniziare con la configurazione della nostra prima applicazione, è utile ricordare che esistono due filoni di sviluppo del framework corrispondenti alle versioni 1 e 2 Struts. Tratteremo delle differenze tra le due versioni in seguito, per ora concentriamoci sulla prima, che sarà argomento predominante della guida. Per prima cosa quindi scarichiamo l'ultima release di Struts 1 (http://struts.apache.org/download.cgi#struts1310).

Figura 2. Download della versione 1.3.10

Struts è distribuito sia sotto forma di codice sorgente (source), sia tramite i "file binari" (full distribution). Scaricare il codice sorgente garantisce un maggior controllo sull'ambiente in cui si effettua la compilazione, ma non è adatto ai principianti. Se non si hanno particolari esigenze (come la modifica o l'inclusione di una classe java nella propria installazione), si può tranquillamente usare la distribuzione binaria.

Per i nostri esempi utilizziamo la "distribuzione binaria". Possiamo quindi cliccare sul link sotto Full Distribution.

Una volta estratto l'archivio, troviamo diverse cartelle. Il framework è composto da circa 300 classi Java, divise in otto package principali (il numero delle classi è approssimativo perché il framework subisce di continuo aggiunte e aggiustamenti).

Struttura di una semplice applicazionePer esaminare la struttura delle cartelle di una semplice applicazione Struts possiamo servirci dei

7

Page 8: HTML Guida Struts

file .war di esempio che troviamo nella cartella apps dell'archivio estratto.

Questi esempi risultano parecchio interessanti soprattutto per chi inizia. Infatti, per entrare nella logica di Struts e applicare il ciclo di vita delle richieste, che abbiamo mostrato nella lezione precedente, è utile esaminare la struttura delle cartelle di un progetto.

Per farlo abbiamo diverse possibilità: possiamo ad esempio rinominare il file struts-blank-1.x.x.war in ProvaStruts.war ed effettuare il deploy su un container come Tomcat o JBoss.

Una alternativa ancora più semplice è quella di utilizzare un tool come Eclipse per effettuare le nostre prove e, siccome siamo nell'ambito di applicazioni JEE, scarichiamo Eclipse per sviluppatori JEE (http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/galileor)

Possiamo importare il progetto in Eclipse da menu File -> Import e scegliendo il formato Web

Figura 3. Importare il file .war in Eclipse

Ogni applicazione Web J2EE al di sotto della cartella in cui viene installata (ad esempio webapp di Tomcat) rispetta una struttura simile a quella che troviamo anche nel nostro progetto su Eclipse:

WebContent (da considerarsi la 'root' dell'applicazione)|+-- WEB-INF | || +-- src (contiene il codice delle nostre servlet)| || +-- classes | || +-- lib (qui ci sono le librerie del framework Struts)| || +-- tags | +-- META-INF| +-- pages (contiene le JSP per le viste)

Figura 4. Struttura delle cartelle

8

Page 9: HTML Guida Struts

Alcuni di questi contenitori come WEB-INF sono fissi, ma possiamo personalizzare le altre directory modificando il file di configurazione della nostra applicazione. Ricapitolando:

• WebContent è la root dell'applicazione. Qui possiamo inserire le nostre pagine dinamiche (le viste JSP) organizzate in cartelle e tutta la parte statica del sito come le pagine HTML, i fogli di stile e le immagini.

• WEB-INF contiene i sorgenti delle azioni e i file di configurazione xml • lib contiene le librerie del framework e gli altri JAR utili all'applicazione. In generale,

quando non abbiamo uno strumento automatico a farlo per noi, dobbiamo copiare la cartella lib che troviamo nell'archivio di Struts all'interno della nostra applicazione

• classes: una cartella contenente le classi compilate dell'applicazione organizzate in cartelle corrispondenti alla struttura dei package

Il deployment descriptor per Struts

Il web.xml è il descrittore di deploy usato per configurare qualsiasi Web application sviluppata con tecnologia J2EE (http://java.html.it/guide/leggi/136/guida-j2ee/), quindi anche un'applicazione Struts avrà il suo descrittore. In più, per la configurazione di una applicazione Struts, abbiamo bisogno di un secondo file, parimenti importante: lo struts-config.xml.

In questa lezione però analizziamo i passi necessari a scrivere un web.xml per Struts, mentre approfondiremo lo struts-config.xml nella prossima lezione.

Il file web.xml contiene le informazioni di configurazione necessarie all'application server, per caricare i componenti necessari all'avvio dell'applicazione.

Questo file serve infatti a descrivere tutti i componenti dell'applicazione Web, contiene informazioni come:

• Parametri ed inizializzazione ServletContext • Contenuto localizzato • Configurazione della sessione • Definizione Servlet/JSP • Mapping Servlet/JSP • Riferimenti a tag library • Mappature a tipi MIME • Lista di file di Welcome • Pagine di errore • Informazioni sulla sicurezza

9

Page 10: HTML Guida Struts

Se lo apriamo con un tool come Eclipse, riusciamo ad esaminarne meglio le aree principali:

Figura 5. Web.xml su Eclipse

Una curiosità interessante: Eclipse mette in verdino, vicino ad ogni tag, i tag children previsti dal suo XML Schema.

Sebbene oggi gli ambienti di sviluppo provvedano alla compilazione automatica di questo file, è sempre bene conoscerne la struttura. Perciò possiamo provare a creare un file web.xml per la nostra applicazione, a partire da uno vuoto:

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web app_2_3.dtd">

<web-app>

</web-app>

Configurare la ActionServletIl primo passo, uno dei più importanti, consiste nel configurare la ActionServlet che si occuperà di ricevere e smistare tutte le richieste dell'applicazione (il nostro controller). Quindi provvediamo a configurare l'istanza della servlet nel seguente modo:

<servlet><servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param></servlet>

10

Page 11: HTML Guida Struts

È importante notare che abbiamo associato alla servlet il file di configurazione (struts-config.xml), che, in questo modo, sarà caricato all'avvio dell'applicazione.

Il mapping delle servletIl passo successivo, necessario a configurare la servlet controller di Struts nel web.xml, lo compiamo scrivendo il "mapping delle servlet". Utilizziamo l'elemento <servlet-mapping> nel seguente modo:

<servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern></servlet-mapping>

In altre parole abbiamo detto all'application server di girare tutte le richieste che hanno il suffisso .do, alla servlet ActionServlet.

La taglibStruts mette a disposizione dei tag JSP e per utilizzarli dobbiamo dichiarane l'uso all'avvio dell'applicazione. Per farlo elenchiamo le librerie di tag nel web.xml, grazie all'elemento <taglib>:

<taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location></taglib>

In questo caso abbiamo dichiarato la libreria struts-html ma come vedremo più avanti non è l'unica messa a disposizione da Struts.

Pagina di benvenuto ed erroriInfine nel deployment descriptor, anche se non vale per le applicazioni che usano Struts, può essere gestita la pagina di benvenuto dell'applicazione:

<welcome-file-list> <welcome-file>index.jsp</welcome-file></welcome-file-list>

e gli errori HTTP, inserendo i relativi codici (404, 500, etc.):

<error-page> <error-code>404.jsp</error-code> <location>404.jsp</location></error-page>

Per effettuare prove o verifiche è ecco un esempio completo di web.xml (img/xeb.xml.html) per un'applicazione Struts.

Il file di configurazione 'struts-config.xml'

11

Page 12: HTML Guida Struts

Per caricare e creare all'avvio tutti i componenti necessari all'applicazione, Struts fa riferimento ad un file di configurazione chiamato struts-config.xml. Questo file ci permette di specificare in maniera dichiarativa il comportamento dei componenti del framework, evitando che le informazioni e il comportamento siano inseriti rigidamente nel codice delle applicazioni.

Questo fornisce agli sviluppatori la flessibilità necessaria ad inserire le proprie estensioni, che il framework può utilizzare in maniera dinamica.

Lo stuts-config si basa sul formato XML e può essere validato con il DTD di Struts, analizziamone la struttura.

Il tag root dello struts-config è <struts-config>, all'interno del quale troviamo cinque sezioni:

• global-forwards • form-beans • action-mappings • message-resources • plug-in

In questa lezione le presentiamo brevemente, ma ce ne occuperemo più approfonditamente nel corso della guida.

global-forwardsIn questa sezione possiamo creare delle associazioni tra particolari nomi (che specificano azioni del controller) e i relativi percorsi (che specificano delle viste), stabilendo dei forward validi a livello "globale" nell'applicazione.

In altre parole non si fa altro che mappare le condizioni di ritorno di una richiesta con particolari Jsp. Lo facciamo utilizzando un elemento <forward> per ogni associazione, grazie alle proprietà name e path.

Un esempio può essere dato da una pagina globale per gli errori, scrivendo una entry nel global-fowards in questo modo:

<global-forwards> <forward name="error" path="/error.jsp"/></global-forwards>

Grazie a questa configurazione, quando in caso di errore viene richiamata l'action error, l'applicazione inoltra la richiesta dell'utente alla Jsp con path /error.jsp.

Analizziamo gli attributi più importanti per configurare un global-forward:

Attributo Descrizione

classNameServe a dichiarare la classe che estende il bean di configurazione e che manterrà tutte le informazioni di forward. Se non specificata, la classe predefinita sarà org.apache.struts.action.ForwardConfig

Name È il nome (unico) che servirà a riferirsi a questo forward nell'applicazione. Questo attributo è obbligatorio

path È l'URI verso cui dovrebbe avvenire il forward. È un attributo obbligatorio e deve cominciare con il carattere "/"

12

Page 13: HTML Guida Struts

form-beansLa seconda parte serve a definire i form bean, particolari classi che contengono i dati inseriti in un form all'interno di una Jsp. Si dichiara uno o più form bean nel seguente modo:

<form-beans> <form-bean name="..." type="..." /></form-beans>

Ecco gli attributi più importanti per configurare un form bean:

Attributo Descrizione

className Quando non si vuole utilizzare il bean di configurazione standard di Struts, bisogna specificare in questo attributo la classe creata nell'applicazione che la sostituisce

Name È il nome (unico) che servirà a riferirsi a questo form bean in tutta l'applicazione. Questo attributo è obbligatorio

Type Il nome di una classe Java che estende la classe ActionForm di StrutsAnalizzeremo meglio la struttura e le tipologie dei form bean nei capitoli successivi.

action-mappingsIn questa sezione definiamo le action. Per ogni azione inseriamo un elemento <action> e ne specifichiamo sia le caratteristiche (grazie alle proprietà come path, name, parameters, etc.) sia i forward dell'azione stessa (grazie ad elementi <forward>). Ecco come pùo presentarsi la dichiarazione di una action:

<action-mappings> <action path="/..." name="..." scope="..." type="..." parameter="..." validate="..."> <forward name="..." path="/..." /> </action></action-mappings>

Analizziamo gli attributi più importanti per definire un action-mapping:

Attributo Descrizione Necessità

pathÈ il percorso per la request inviata. Deve iniziare con il carattere "/" e senza l'estensione del nome del file. In altre parole è il nome dell'azione

obbligatorio

name È il nome del form bean associato all'azione facoltativo

inputIl path per il modulo di immissione dati verso il quale deve essere reindirizzato il controllo se si verifica un errore di validazione

obbligatorio se è specificato l'attributo name

validateValore booleano (false o true) che indica se il metodo validate() del form bean, deve essere invocato prima di eseguire l'action, per default è true

facoltativo

scopeIndica quale visibilità abbia il form bean e assumere i valori request (relativo solamente alla sola richiesta) o session (relativo per tutta la sessione dell'utente)

facoltativo

Forward Questo elemento ci permette di indicare il nome (attributo facoltativo, può non

13

Page 14: HTML Guida Struts

name) e il path (attributo path) di una servlet o di una pagina JSP verso cui verrà effettuato il forward

essere dichiarato se presenti gli attributi type o include.

type

È usato per elaborare la request se gli attributi forward o include non sono specificati. Si deve dichiarare il nome di una classe Java che estende la org.apache.struts.action.Action

facoltativo ed esclusivo rispetto a forward e include

include Indica il path di una servlet o di una pagina JSP che saranno incluse nella response

facoltativo ed esclusivo rispetto a forward e type

attributeServe a dichiarare il nome di un attributo necessario ad accedere al form bean dell'action da dichiarare (vedremo meglio questo meccanismo in seguito)

facoltativo e ha precedenza rispetto all'attributo name

parameter

È utilizzato per passare informazioni extra all'istanza dell'action selezionata. All'interno della action, possiamo recuperare un parametro definito in questo modo grazie al metodo getParameter()

facoltativo

classNameServe ad indicare una classe alternativa per il mapping e la configurazione dell'action. Di default Struts usa org.apache.struts.ActionMapping

facoltativo

Ecco un esempio di action mapping, in cui associamo il path "/azione" alla classe it.html.struts.MyAction, indichiamo che utilizzeremo il form myForm e che per gli errori ci serviamo della vista dataerror.jsp:

<action path = "/azione" type = "it.html.struts.MyAction" name = "myForm" input = "/WEB-INF/jsp/dataError.jsp"> <forward name="OK" path="/WEB-INF/jsp/viewResult.jsp"/> <forward name="ERROR" path="/WEB-INF/jsp/busError.jsp"/></action>

message-resourcesI message-resources, sono classi utili per gestire i messaggi in modo unificato nell'applicazione. Sono particolarmente utili per applicazioni multilingua.

<message-resources parameter="MessageResources" />

Vedremo che nelle viste si farà riferimento a delle chiavi (key) che saranno poi associate ai messaggi corrispondenti.

plug-inInfine abbiamo la parte dedicate alla dichiarazione dei plugin usati nell'applicazione. Osserviamo come aggiungere alla nostra applicazione uno dei plugin più utilizzati del framework, il validator che permette di validare i parametri inseriti in un form:

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

14

Page 15: HTML Guida Struts

<set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml"/></plug-in>

File di configurazione multipliNei progetti di grandi dimensioni è possibile specificare più di un file di configurazione. Ciò consente, ad esempio, l'importazione di componenti specifici per particolari rami dell'applicazione, o di avere più applicazioni Struts sullo stesso server.

Per dichiarare un nuovo ramo dell'applicazione, ad esempio la sezione blog, dobbiamo agire sul web.xml ed aggiungere un parametro all'elemento <servlet>

<init-param> <param-name>config/blog</param-name> <param-value>/WEB-INF/struts-blog-config.xml</param-value></init-param>

Hello World con Struts

In questa lezione vediamo come su possa realizzare una applicazione di benvenuto (la classica "Hello World"), che visualizza un messaggio di benvenuto. Iniziamo ad approfondire alcuni concetti e ne lasceremo altri da trattare in seguito.

Dopo aver creato il nostro progetto J2EE con Eclipse importiamo il file struts-blank-1.x.x.war così come abbiamo visto nella lezione precedente (http://java.html.it/guide/lezione/4556/creare-un-progetto-struts-con-eclipse/). Ecco ciò che otteniamo lanciando l'applicazione (per esempio su TomCat):

Figura 6. Risultato dell'applicazione

In precedenza abbiamo visto come questo progettino rappresenti l'ossatura di base di una applicazione Struts. In questa lezione continueremo ad analizzare i file di questa applicazione, per comprenderne il funzionamento.

I componenti principali dell'applicazione struts-blank sono:

15

Page 16: HTML Guida Struts

• Il file WEB-INF/web.xml • Il file WEB-INF/struts-config.xml • I file .jsp (index.jsp, pages/Welcome.jsp) • Il file WEB-INF/classes/message.properties • Le api di Struts contenute nella cartella WEB-INF/lib

Il file web.xml come abbiamo detto nelle lezioni precedenti, non è un file di Struts ma il file di configurazione per ogni applicazione J2EE.

Apriamo il file e osserviamo il contenuto degli elementi <servlet> e <servlet-mapping>: è sovrapponibile alla configurazione standard già esaminata in precedenza:

<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>2</load-on-startup></servlet>

<servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern></servlet-mapping>

index.jsp

Infatti anche qui troviamo la configurazione dell'ActionServlet e la sua mappatura, con la delega alla classe ActionServlet di gestire tutti i file che abbiano estensione .do. Infine definiamo come file di partenza la vista index.jsp.

Esaminiamo quindi il file configurazione WEB-INF/struts-config.xml.

<global-forwards> <forward name="welcome" path="/Welcome.do"/></global-forwards>

Nel global-forwards diciamo che quando viene inviata una richiesta alla pagina /Welcome.do, questa viene associata ad un forward di nome welcome

<action-mappings> <action path="/Welcome" forward="/pages/Welcome.jsp"/></action-mappings>

Questa dicitura serve per configurare l'action Welcome.do definendone il forward alla pagina /pages/Welcome.jsp. Inoltre abbiamo la dichiarazione del message-resource:

<message-resources parameter="MessageResources" />

Lo struts-config della nostra piccola applicazione contiene l'esempio per la configurazione di qualsiasi componente di Struts.

Adesso passiamo alle due viste. La prima è la index.jsp:

<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>

16

Page 17: HTML Guida Struts

<logic:redirect forward="welcome"/>

Si dichiara il tag <logic> e si effettua un forward all'action con il nome welcome configurata nello struts-config.

La pagina pages/welcome.jsp si compone invece nel seguente modo:

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %><%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>

<html:html><head><title><bean:message key="welcome.title"/></title><html:base/></head><body bgcolor="white">

<logic:notPresent name="org.apache.struts.action.MESSAGE" scope="application"> <font color="red"> ERROR: Application resources not loaded -- check servlet container logs for error messages. </font></logic:notPresent>

<h3><bean:message key="welcome.heading"/></h3><p><bean:message key="welcome.message"/></p>

</body></html:html>

Nelle lezioni successive chiariremo tutte le sue parti, per adesso commentiamo solo queste righe:

<h3><bean:message key="welcome.heading"/></h3><p><bean:message key="welcome.message"/></p>

Che servono a prelevare dei messaggi dal "message resource" per comporre la pagina Jsp al momento della compilazione. Per prelevare i messaggi basta specificare la chiave.

Infine abbiamo il file MessageResources.properties (nella cartella WEB-INF/src/java/) in cui troviamo le definizioni per tutti i messaggi con le relative chiavi.

welcome.title=Struts Blank Applicationwelcome.heading=Welcome!welcome.message=To get started on your own application, copy the struts-blank.war to a new WAR file using the name for your application. Place it in your container's "webapp" folder (or equivalent), and let your container auto-deploy the application. Edit the skeleton configuration files as needed, restart your container, and you are on your way! (You can find the MessageResources.properties file with this message in the /WEB-INF/src folder.)

Questo sistema, che permette di associare i messaggi alle chiavi, risulta molto utile, specie quando vogliamo internazionalizzare l'applicazione.

Regole e consigli per scrivere applicazioni con Struts

Prima di entrare nel dettaglio dei vari componenti di Struts è utile fissare alcune regole che ci

17

Page 18: HTML Guida Struts

aiutino a realizzare applicazioni stabili e revisionabili. Alcune di queste regole hanno carattere generale: sono valide per Struts ma applicabili anche allo sviluppo con altri framework.

Processo di sviluppoStruts si basa sul paradigma MVC, ecco un possibile processo di sviluppo di base per tutte le applicazioni:

1. Disegnare (e poi creare) tutte le viste che rappresentano l'interfaccia utente dell'applicazione 2. Creare e distribuire tutti gli ActionForm (vedremo meglio in seguito di che si tratta)

utilizzati dalle viste 3. Scrivere la logica applicativa realizzando i componenti del Controller 4. Definire le relazioni che esistono tra le Viste e il Controller (struts-config.xml) 5. Apportare le modifiche appropriate al file web.xml 6. Mandare in esecuzione l'applicazione

Abbiamo omesso cose molto importanti come la gestione dei requisiti e l'adozione di una suite per lo unit testing, ma solo per concentrarci meglio sul framework.

Scrivere il markup solo nelle visteUn'altra regola impostante per ottenere codice efficiente e per soddisfare i principi del MVC è quello di scrivere il markup HTML solo nelle nelle viste, quindi nelle pagine Jsp.

Sarebbe infatti possibile rispondere ad una richiesta direttamente dall'Action, sfruttando la funzione write del componente out. L'oggetto out risulta molto utile soprattutto per accedere ai parametri e alle proprietà di una sessione, ecco un modo poco ortodosso di utilizzarlo:

out.write("<html><body>Ciao</body></html>");

Questa funzione ci potrebbe "risparmiare la fatica" di creare una pagina Jsp, ma rende le viste non modificabili e può creare problemi a tutta l'architettura Struts.

Tutte le Action finiscono con il .doQuando definiamo il controller nel web.xml, dichiariamo una classe di tipo filter, questo significa che stabiliamo un url-pattern (una espressione) che determina quali richieste debbano essere gestite dalle nostre Action.

Lo standard di Struts prevede il suffisso .do per le Action, pertanto è buona norma aderire a questa convenzione, e terminare con il .do tutte le nuove Action che creiamo. Questo è utile soprattutto per la manutenzione e per non creare confusione nel lavoro di gruppo.

Sui jar• Non creare package con namespace già presenti in Struts o in altri framework come ad

esempio org.apache.struts. • Quando si caricano i jar di Struts stare attenti a non avere jar di versioni differenti • Se si usano altri framework consultare sempre la compatibilità e soprattutto stare attenti a

quando si caricano i jar. In ogni caso Struts è quello di alto livello quindi saranno gli altri framework a cambiare i jar. È consigliabile creare una nuova cartella e caricare dentro tutti i jar di struts e degli altri framework così da non avere problemi quando esportiamo

18

Page 19: HTML Guida Struts

l'applicazione.

Test e configurazione• Per ogni Action o per ogni processo sviluppato è utile testare il funzionamento

dell'applicazione. Infatti con Struts il lavoro di un programmatore consiste soprattutto nella stesura dei file di configurazione, dove facilmente si può sbagiare qualche percorso, qualche lettera, etc.

• Lo Struts-config è caricato all'avvio dell'Application Server, quindi se si effettuano modifiche è necessario ricordare di riavviare l'application Server

ActionServlet

In questo capitolo approfondiamo il Controller, la parte più importante del framework Struts. Il Controller è composto di i 4 elementi fondamentali, che hanno responsabilità quali ricevere un input da un client, attivare le operazioni secondo la logica applicativa e gestire le viste e l'interfaccia con il client.

• la classe ActionServlet • la classe Action • i Plugin • il RequestProcesser

La classe ActionServlet e il RequestProcessorLa classe org.apache.struts.ActionServlet è un elemento fondamentale per le applicazioni Struts. Si tratta del componente che realizza il Controller nella architettura MVC.

Il suo compito è, infatti, quello di gestire le richieste client e determinare quale org.apache.struts.action.Action processerà la richiesta arrivata. Funziona come un Action Factory, creando istanze di classi Action in base alle richieste ricevute.

La ActionServlet è una servlet che, come tutte le altre servlet, estende la classe javax.servlet.http.HttpServlet e quindi implementa tutti i metodi del ciclo di vita di una servlet (http://java.html.it/guide/lezione/784/le-servlet/), incluse le attività di init(), doGet(), doPost() e destroy.

I due punti di ingresso per l'ActionServlet sono essenzialmente gli stessi delle altre servlet: doGet() e doPost().

// Codice di doGet() e doPost()

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { process (request, response);}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { process (request, response);}

19

Page 20: HTML Guida Struts

L'implementazione di questi metodi fa esattamente la stessa cosa, ossia chiamare il metodo process(). Per capire meglio questo comportamento esaminiamo, passo dopo passo, le attività compiute dall'ActionServlet quando riceve una richiesta:

1 I metodi doPost() o doGet() ricevono una richiesta e invocano il metodo process()

2

Il metodo process() ottiene il RequestProcessor corrente e ne invoca a sua volta il metodo process().

Se si intende estendere l'ActionServlet, il posto giusto per la personalizzazione è l'oggetto RequestProcessor: contiene la logica che il Controller Struts esegue su ogni richiesta

3Il metodo RequestProcessor.process() è il luogo dove la richiesta viene effettivamente servita. Questo metodo reperisce, dal file struts-config.xml, l'elemento <action> che corrisponde al path submitted della richiesta

4Quando il metodo RequestProcessor.process() trova una <action> in match, va alla ricerca dell'entry <form-bean> referenziato dall'elemento <action>

5Quando il metodo RequestProcessor.process() conosce il "fully qualified name" del FormBean, crea o reperisce un'istanza dell'ActionForm nominato dall'elemento <form-bean> e popola i membri di istanza con i valori che arrivano dalla richiesta

6Quando i dati dell'ActionForm sono stati caricati, il metodo RequestProcessor.process() chiama il metodo ActionForm.validate(), che controlla la validità dei valori passati

7Il metodo RequestProcessor.process() conosce tutto ciò che gli serve e può servire la richiesta. Reperisce il "fully qualified name" della classe Action e chiama il metodo execute()

8

Quando la classe azione ritorna dal suo processing, il suo metodo execute() ritorna un oggetto ActionForward che viene utilizzato per determinare il target della transazione. Il metodo RequestProcessor.process() riacquisisce il controllo e la richiesta viene indirizzata al target

A questo punto l'ActionServlet ha completato l'elaborazione della richiesta ed è pronto per servirne delle altre.

Al fine di delgare all'ActionServlet l'unica responsabilità di ricevere e rispondere ad una request chiamando la giusta Action, dalla versione 1.1 del framework è stata introdotta una nuova classe, il RequestProcessor (org.apache.struts.action.RequestProcessor), al fine di elaborare la request per il controller. Grazie a questo disaccoppiamento è possibile personalizzare e modificare il modo in cui viene elaborata la richiesta.

Configurare l'ActionServletCome ogni altra servlet Java, la ActionServlet di Struts deve essere configurata nel deployment descriptor. Quindi una volta aperto il file web.xml, possiamo inserire le nostre impostazioni utilizzando l'elemento <servlet>.

Una pratica comune consiste nell'utilizzare l'elemento <load-on-startup> per essere certi che l'ActionServlet venga avviata quando il container avvia l'applicazione Web.

Ecco un esempio di <servlet> entry che descrive ActionServlet:

<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

20

Page 21: HTML Guida Struts

<init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <param-name>debug</param-name> <param-value>4</param-value> <init-param></init-param> <load-on-startup>1</load-on-startup></servlet>

Le Action

Le Action sono gli strumenti grazie ai quali il Controller di Struts gestisce le attività. Ogni Action rappresenta una funzione dell'applicazione, quindi è qui che scriviamo la logica applicativa dei nostri progetti.

La classe Action disaccoppia le richieste del client dall'applicazione. In altre parole un oggetto di tipo Action è un'estensione del controller e fa da ponte tra le azioni client-side dell'utente e le operazioni della logica applicativa.

Ogni Action, come abbiamo già detto (http://java.html.it/guide/lezione/4558/il-file-di-configurazione-strutsconfigxml/), deve essere dichiarata e configurata nel file struts-config.xml e non nel web.xml. Il suo nome deve terminare con .do, è questo che permette alla richiesta di essere processata da Struts e non come una semplice servlet Java.

Le Action servono ad esempio a ricevere le richieste dai form, ad elaborare i dati e a lanciare le View per la visualizzazione delle informazioni. Per realizzare le Action, è necessario:

• Creare una classe che estenda org.apache.struts.action.Action • Implementare il metodo execute() aggiungengo la logica di business della nostra

applicazione • Compilare la nuova Action e spostarla nel classpath dell'applicazione Web • Aggiungere un elemento <action> al file struts-config.xml all'applicazione che descrive la

nuova azione

Esaminiamo più in dettaglio alcuni di questi passi.

Creare una ActionDichiarare una nuova Action è molto semplice, è sufficiente estendere la classe base e ricordare di importare tutti i namespace necessari (se utilizziamo un IDE ci saranno comunque suggeriti):

import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.Action;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;

public class EsempioAction extends Action {

// Qui scriviamo la Action

21

Page 22: HTML Guida Struts

}

Il metodo execute()La classe base Action ci da l'opportunità e il compito di effettuare l'override del metodo execute(), riscrivendo questo metodo, possiamo indicare le operazioni che vogliamo far compiere alla nostra azione. In altre parole è qui che inseriamo la "logica di business".

Il metodo execute() viene invocato dal controller quando viene ricevuta una richiesta. Da non sottovalutare, per il buon funzionamento dell'applicazione, che una classe Action viene istanziata una sola volta, all'avvio dell'applicazione, quindi occorre garantire che tutte le Action operino correttemente in un ambiente multithread, proprio come si fa quando si sviluppa una servlet.

Le funzioni principali di execute() sono:

• compiere la logica dell'applicazione • instradare la richiesta indicando al Framework il passo successivo da eseguire

Azioni HTTP e Custom

Struts contempla due definizioni per execute().

La prima serve a dichiarare azioni custom che non sono specificatamente HTTP. Questa implementazione del metodo è analoga alla classe javax.http.servlet.GenericServlet; e la sua signature è la seguente:

public ActionForward execute(ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response ) throws IOException, ServletException

La seconda implementazione viene utilizzata invece per dichiarare azioni HTTP. Ecco la sua signature:

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException

Campo DescrizioneActionMapping Contiene le informazioni di deployment per un particolare Action beanActionForm Rappresenta gli input del Form contenente i parametri della richiestaHttpServletRequest È un riferimento all'oggetto HTTP RequestHttpServletResponse È un riferimento all'oggetto HTTP ResponseDopo aver esaminato i parametri passati al metodo execute(), bisogna dare un'occhiata al suo tipo di ritorno.

ActionForwardQuesto oggetto viene utilizzato dal RequestProcessor per determinare la destinazione successiva della richiesta. Qui si può determinare ad esempio, se sarà lanciata una vista JSP o

22

Page 23: HTML Guida Struts

un'altra azione.

// Esempio di execute()

public class EsempioAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (form!=null) { // 1. Creazione del form // (effetuiamo il cast dal form in ingresso) SkeletonForm actionForm = (SkeletonForm) form; // 2. Aggiungere qui la Business Logic // 3. return con un appropriato ActionForward return mapping.findForward("success"); } }}

Nella costruzione delle Action, si segue una procedura comune:

1. effettuare un cast dell'ActionForm referenziato 2. aggiungere la specifica logica di business 3. utilizzare il metodo ActionMapping.findForward() per trovare l'oggetto ActionForward che effettua un match con il sottoelemento <forward> nella definizione di <action> (nel file struts-config.xml)

4. restituire l'oggetto ActionForward trovato

Configurazione della classe ActionLe classi Action si configurano nel file struts-config.xml, poiché si tratta di oggetti specifici di Struts.

L'elemento che viene utilizzato per descrivere un'azione Struts è <action>. e la classe che definisce gli attributi dell'elemento <action> è org.apache.struts.action.ActionMapping.

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>

<form-beans> <!-- qui dichiariamo che il form 'lookupForm' sarà inviato--> <!-- all'action 'esempio' nel campo ActionForm --> <form-bean name="lookupForm" type="esempio.LookupForm" /> </form-beans> <action-mappings> <!-- la location /Lookup lancerà il nostro form -->

23

Page 24: HTML Guida Struts

<action path="/Lookup" type="esempio.LookupAction" name="lookupForm" > <!-- le viste da collegare all'esito dell'action --> <forward name="success" path="/quote.jsp" /> <forward name="failure" path="/index.jsp" /> </action> </action-mappings> </struts-config>

Vedremo in seguito come estendere il mapping per definire attributi <action> addizionali.

DispatchAction

Spesso le azioni sembrano essere troppo numerose e troppo piccole, sarebbe utile raggruppare azioni correlate in una classe facilitando il riutilizzo.

A tale scopo Struts mette a disposizione le DispatchAction (org.apache.struts.action.DispatchAction). Il principio alla base è che ci possano essere funzionalità correlate per un servizio che, invece di essere suddivise in molteplici classi Action, si possono tenere insieme nella medesima classe.

DispatchAction è una classe astratta che estende la classe Action. Anziché avere un singolo metodo execute, si ha un metodo per ciascuna azione logica.

Nella request, infatti, bisogna inserire un parametro di nome method che sarà usato dalla DispatchAction per determinare quale metodo invocare.

Per implementare una DispatchAction bisognerà creare:

1. una classe action handler che estenda DispatchAction; 2. un metodo per ciascuna azione logica; 3. un action-mapping per questo action handler

// Un esempio di DispatchAction

import javax.servlet.http.*;import javax.servlet.*;import org.apache.struts.actions.*;import org.apache.struts.action.*;

public class UserDispatchAction extends DispatchAction {

public ActionForward remove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("REMOVE USER!!!!"); return mapping.findForward("success"); } public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

24

Page 25: HTML Guida Struts

System.out.println("SAVE USER!!!!"); return mapping.findForward("success"); }}

È utile notare che tutti i metodi hanno la stessa firma del metodo Action.execute().

Produciamo il bean che conterrà il valore di method, unica proprietà del form inviante:

// Bean che contiene il valore di methodimport javax.servlet.http.*;import org.apache.struts.action.*;

public class UserForm1 extends ActionForm {

private String method = null; public String getMethod() { return method; } public void setMethod(String method) { this.method = method; }

public void reset(ActionMapping mapping, HttpServletRequest request) { this.method = method; }}

Il terzo step è quello per creare un action mapping per questo action handler e aggiungendo un elemento <form-bean> nel struts-config.xml:

<form-beans> <form-bean name="userForm1" type="fulvios.UserForm1" /></form-beans>

<action path="/dispatchUserSubmit" type="fulvios.UserDispatchAction" parameter="method" input="/userForm1.jsp" name="userForm1" scope="request" validate="false"> <forward name="success" path="/success.jsp" /></action>

Ecco quindi lo step finale: creare la userForm1.jsp.

<%@ page language="java" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html><body><html:form action="/dispatchUserSubmit"> action: <html:select property="method" size="2"> <html:option value="save">Save</html:option> <html:option value="remove">Remove</html:option> </html:select> <br/> <html:submit/><html:cancel/></html:form>

25

Page 26: HTML Guida Struts

<%@ page language="java" %>

success!!

In questo esempio abbiamo la DispachtAction che contiene due metodi remove() e save(). Questa classe raggruppa tutte le funzionalità a disposizione dell'utente. Se non avessimo utilizzato una DispachtAction avremmo dovuto creare due Action e implementare i due metodi excute().

DispacthAction utilizza la reflection per individuare un metodo che corrisponda perfettamente al nome contenuto nel valore del parametro della richiesta, controllando anche la corrispondenza del numero e del tipo degli argomenti. Una volta trovato, il metodo sarà invocato e l'oggetto ActionForward restituito proprio come per una qualunque Action.

Sebbene si tratti di una soluzione valida, è importante utilizzarla con criterio. La DispatchAction risulta particolarmente utile quando le classi da raggruppare rappresentano azioni simili tra loro o hanno parti comuni da eseguire prima di effettuare operazioni specifiche. Ad esempio se dobbiamo prelevare dei dati da un database e modificarli in modo differente a seconda della scelta di un utente conviene utilizzare una DispatchAction per evitare di scrivere uno stesso metodo più volte. Inoltre combinando le operazioni, si renderà più semplice la manutenzione dell'applicazione, infatti se si vuole cambiare l'implementazione di una funzionalità basterà agire solo su una classe.

LookupDispatchAction

La classe LookupDispatchAction (org.apache.struts.actions.LookupDispatchAction), è una sottoclasse della DispatchAction e come quest'ultima ci permette di specificare metodi multipli. Ciascun metodo poi sarà invocato utilizzando il meccanismo del parametro speciale da inserire nelle richieste, parametro che viene indicato nel file di configurazione.

Mentre la DispatchAction usa il valore del parametro della request per determinare quale metodo deve essere invocato, la LookupDispatchAction usa il valore del parametro della request per effettuare un reverse lookup dal resource bundle usando il valore del parametro e per farlo corrispondere a un metodo della classe.

In altre parole ci permette di pescare valori dal file delle risorse in modo dinamico.

Per utilizzare LookupDispatchAction è necessario eseguire i seguenti step:

1. Creare un action handler che erediti LookupDispatchAction 2. Creare un metodo che rappresenti ciascuna azione logica 3. Implementare il metodo getKeyMethodMap per mappare le chiavi del file di risorsa ai

nomi dei metodi 4. Creare un action mapping per questo action handler utilizzando l'attributo parameter per

specificare quale parametro conterrà il nome del metodo che si vuole invocare nelle richieste 5. Impostare i messaggi nel resource boundle per le etichette e i valori per i pulsanti 6. Utilizzare bean:message per mostrare le etichette sul pulsante

Il primo step è creare una classe action handler che erediti LookupDispatchAction (codice completo (http://html.it/guide/img/struts/lookupdispatch_example.html)):

26

Page 27: HTML Guida Struts

// Handler che eredita LookupDispatchActionpublic class UserLookupDispatchAction extends LookupDispatchAction {

// È necessario implementare questo metodo che mappi // le chiavi del file di risorse ai nomi dei metodi Map getKeyMethodMap() { Map map = new HashMap(); map.put("userForm.remove", "remove"); map.put("userForm.save", "save"); return map; }

//...

Questa classe implementa il metodo getKeyMethodMap() che restituisce un oggetto di tipo java.util.Map contenente una serie di coppie del tipo chiave/valore. Le chiavi di questo Map dovrebbero corrispondere a quelle del resource bundle, mentre il valore associato dovrebbe essere il nome del metodo della sottoclasse LookupDispatchAction. Questo valore sarà invocato quando è incluso un parametro della request corrispondente al messaggio del resource bundle per la chiave.

Produciamo il bean che conterrà il valore di method, unica proprietà del form inviante:

import javax.servlet.http.*;import org.apache.struts.action.*;

// Bean che contiene il valore di method

public class UserForm2 extends ActionForm {

private String method = null; public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public void reset(ActionMapping mapping, HttpServletRequest request) { this.method = method; }}

Creiamo un action mapping (struts-config.xml):

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>

<form-beans> <form-bean name="userForm2" type="simone.UserForm2" /></form-beans>

<action-mappings>

<action path="/lookupDispatchUserSubmit" type="simone.UserLookupDispatchAction" input="/userForm2.jsp"

27

Page 28: HTML Guida Struts

name="userForm2" parameter="method" scope="request" validate="true">

<forward name="success" path="/success.jsp" /></action>

</action-mappings> </struts-config>

Scriviamo le nostre viste. Prima il form:

<%@ page language="java" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<!-- Form JSP -->

<html><body><html:form action="/lookupDispatchUserSubmit"> <html:submit property="method"> <bean:message key="userForm.remove" /> </html:submit> <html:submit property="method"> <bean:message key="userForm.save" /> </html:submit>

<html:cancel></html:cancel></html:form></body></html>

poi la pagina con il risultato:

<%@ page language="java" %>

<!-- JSP con il risultato del form -->

<html><body>success!!</body></html>

infine il file di risorse, dove impostiamo le etichette e i valori per i pulsanti:

ApplicationResources_it_IT.propertiesuserForm.save=SalvauserForm.remove=Rimuovi

ApplicationResources_en_US.propertiesuserForm.save=SaveuserForm.remove=Remove

È importante modificare anche il file web.xml a causa dei file di risorse:

<init-param> <param-name>application</param-name> <param-value>ApplicationResources</param-value>

28

Page 29: HTML Guida Struts

</init-param>

Si tratta di un percorso piuttosto lungo semplicemente per determinare quale metodo invocare. L'intento di questa classe è di rendere tutto più facile quando si ha un modulo HTML con pulsanti di immissione multipli con lo stesso nome.

Forward Action

In genere non è una buona prassi quella di inserire, all'interno di una pagina JSP, dei link diretti ad altre pagine JSP, soprattutto per questioni di ordine e manutenzione: in effetti è all'interno del file di configurazione struts-config.xml, che fa parte del Controller, che dovremmo descrivere l'intero flusso dell'applicazione.

In alcune occasioni possiamo però avere la necessità di effettuare un forward da una pagina Jsp a un'altra, senza che in realtà ci sia bisogno di passare per una classe Action. Quello che si vuole è un plain link.

Nell'architettura MVC è compito del controller di elaborare tutte le richieste e selezionare la view per il client. Se si utilizza un link diretto, a un'altra pagina JSP, si stanno violando i confini dell'architettura "Model 2" (l'MVC per applicazioni Web).

Se permettessimo alla nostra applicazione di chiamare direttamente la pagina, il controller non sarebbe in grado di portare a termine i compiti per esso stabiliti nell'architettura MVC. Per risolvere questi problemi Struts mette a disposizione la ForwardAction che esegue semplicemente un forward verso un URI configurato nell'attributo parameter dell'action nello struts-config.

Quindi la ForwardAction ci evita la creazione di una classe Action che effettua solamente un semplice forward.

Prima di esaminare un esempio più consistente vediamo una configurazione tipica di ForwardAction:

<action input="/index.jsp" path="/provaForward" parameter="/pagina.jsp" type="org.apache.struts.actions.ForwardAction"></action>

Quando viene selezionata l'action /provaForward, viene chiamato l'unico metodo della ForwardAction, che effettua un forward a pagina.jsp. La classe ForwardAction è molto utile quando è necessario integrare Struts con altri framework o più pagine Jsp.

EsempioAbbiamo detto che ForwardAction agisce come bridge tra la vista corrente JSP e la pagina alla quale si collega. Utilizza il RequestDispatcher per effettuare un forward alla risorsa Web specificata. È ciò che permette di collegarsi a un'azione invece che direttamente a una pagina JSP.

Ecco alcuni passi necessari per implementare una ForwardAction:

• utilizzare <html:link> con l'attributo action e aggiungere il link alla pagina JSP che punta all'azione

• creare un action mapping nel file di configurazione di Struts che utilizza ForwardAction con

29

Page 30: HTML Guida Struts

l'attributo parameter che specifica il percorso alla JSP

Supponiamo di avere una pagina JSP, coded.jsp, che ha un link diretto su un'altra pagina JSP:

<%@ page language="java" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><html><body>

<html:link page="/index.jsp">Home</html:link>

</body></html>

e di volerla convertire secondo la logica dell'architettura MVC/Model2. In questo caso modifichiamo il tag <html:link>su un'azione. È sufficiente produrre notcoded.jsp:

<%@ page language="java" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><html><body> <html:link action="home">Home</html:link></body></html>

Infine bisogna aggiungere un action mapping all'azione home referenziata dal tag html:link:

<action path="/home" type="org.apache.struts.actions.ForwardAction" parameter="/index.jsp"></action>

Link a forward globaliDa una prospettiva di design, c'è un'ulteriore alternativa all'utilizzo dell'azione ForwardAction, anziché inserire un link a un azione o a una pagina, ci si potrebbe collegare a un global forward. Ecco un esempio di pagina JSP collegata a un global forward:

<%@ page language="java" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><html> <body> <html:link forward="home">Home</html:link> </body></html>

Per permettere ora al codice di funzionare dobbiamo aggiungere un global forward al file di configurazione di Struts che mappi l'azione home:

<global-forwards> <forward name="home" path="/index.jsp" /></global-forwards>

È possibile anche modificare il global forward in modo che punti a un action mapping:

<global-forwards> <forward name="home" path="/home.do" />

30

Page 31: HTML Guida Struts

</global-forwards>

Questa, solitamente, è la pratica migliore, infatti, è più naturale collegarsi a forward che ad azioni.

Forward Attribute vs. ForwardActionStruts permette le due dichiarazioni seguenti nel file struts-config.xml, ma la seconda è sicuramente più snella:

<!-- ForwardAction --><action path="/home" type="org.apache.struts.actions.ForwardAction" parameter="/index.jsp" />

<!-- Forward Attribute --><action path="/home" forward="/index.jsp" />

Forward per accesso Legacy

Supponiamo di avere una risorsa Web legacy che si vuole utilizzare con la validazione form di Struts, purtroppo, la risorsa legacy fa parte di un modello MVC elaborato che è stato creato prima dell'implementazione di Struts.

Per ragioni di semplicità la nostra risorsa legacy sarà una servlet. Essenzialmente si vuole fare in modo che il metodo doGet di una servlet venga chiamato solo se l'ActionForm valida i dati con successo. Ecco la nostra servlet d'esempio:

import javax.servlet.*;import javax.servlet.http.*;import org.apache.struts.action.*;import org.apache.struts.*;

import java.io.*;

public class LegacyServlet extends HttpServlet {

public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ActionMapping mapping = (ActionMapping) request.getAttribute(Globals.MAPPING_KEY); UserForm form = (UserForm)request.getAttribute(mapping.getName()); response.getWriter().println("User name: " + form.getUsername() + " Password: " + form.getPassword()); }}

e questo è lo UserForm.java, che passa UserName e password

import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionMapping;import javax.servlet.http.HttpServletRequest;

public class UserForm extends ActionForm {

31

Page 32: HTML Guida Struts

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

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; } public void reset(ActionMapping mapping, HttpServletRequest request) { this.username = null; this.password = null; }}

Notiamo che la servlet può accedere al contesto che il Framework di Struts ha mappato su request (Codice completo del web.xml (http://html.it/guide/img/struts/legacyforward_webxml_example.html)).

<!-- ... --> <servlet> <servlet-name>legacy</servlet-name> <servlet-class>simone.LegacyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>legacy</servlet-name> <url-pattern>/legacy/roar</url-pattern> </servlet-mapping> <!-- ... -->

Quindi, un post su /legacy/roar causerebbe l'esecuzione del metodo doGet della servlet.

Ora, per mappare questa servlet su un'azione che agisce come form handler, è necessario mettere mano a struts-config.xml:

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config> <form-beans> <form-bean name="userForm" type="simone.UserForm" /> </form-beans> <action-mappings> <action path="/legacy" forward="/legacy/roar" input="/userForm.jsp" name="userForm" parameter="/legacy/roar" validate="true" scope="request"> </action> </action-mappings> </struts-config>

E infine ecco la JSP:

<%@ page language="java" %>

32

Page 33: HTML Guida Struts

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><html><body><html: form action="/legacy"> username: <html:text property="username"/><br/> password: <html:password property="password"/><br/> <html:submit/><html:cancel /></html:form></body></html>

Il RequestDispatcher effettua la chiamata al metodo doGet() della Servlet solo se il metodo execute() della ForwardAction viene chiamato.

Avendo impostato il metodo validate su true nell'action mapping per la servlet, il metodo execute() di ForwardAction viene chiamato solo se ActionForm (UserForm) validates restituisce nessun oggetto ActionError.

MappingDispatchAction e altre Action già pronte

In questa lezione analizzeremo quelle action pronte all'uso, contenute nel package org.apache.struts.actions, che non abbiamo ancora trattato, ma che vale la pena conoscere.

MappingDispatchActionLa MappingDispatchAction è identica alla DispatchAction, solo che in fase di mapping non si specifica più il parametro, ma direttamente il nome del metodo da invocare. La stessa azione sarà mappata con nomi differenti e sarà chiamata a seconda del metodo da invocare.

Riprendendo l'esempio fatto per la DispatchAction nelle lezioni precedenti, dovremo modificare innanzitutto l'estensione della classe, che sarà org.apache.struts.action.MappingDispatchAction. Nello struts-config scriveremo:

<action path="/saveMappingDispatchUserSubmit" type=" fulvios.UserMappingDispatchAction" parameter="save"> <forward name="success" path="/success.jsp" /></action>

<action path="/removeMappingDispatchUserSubmit" type="fulvios.UserMappingDispatchAction" parameter="remove"> <forward name="success" path="/success.jsp" /></action>

Quindi se vogliamo eseguire il metodo save invocheremo l'azione con il nome /saveMappingDispatchUserSubmit mentre per il metodo remove /removeMappingDispatchUserSubmit.

33

Page 34: HTML Guida Struts

BaseActionLa BaseAction è molto simile ad una semplice Action di Struts solo che mette a disposizione il seguente metodo execute():

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception { preProcess(mapping,form,request,response); if (isErrors(request)) { return findFailure(mapping,form,request,response); } try { executeLogic(mapping,form,request,response); } catch (Exception e) { setException(request,e); catchException(mapping,form,request,response); } finally { postProcess(mapping,form,request,response); } if (isErrors(request)) { return findFailure(mapping,form,request,response); } if ((isStruts_1_0()) && (isMessages(request))) { saveErrors(request,getMessages(request,false)); }}

Questo metodo mette a disposizione una parte dove si può implementare una logica di business da effettuare prima di eseguire il processo vero e proprio che sarà contenuto nel metodo executeLogic(). Nel metodo è già compresa la gestione delle eccezioni generale.

IncludeActionLa classe IncludeAction ha la stessa funzionalità della ForwardAction solo che permette l'integrazione di servlet con l'applicazione Struts. Si configura allo stesso modo della ForwardAction solo che l'attributo parameter deve specificare il path di una servlet, mentre type deve essere org.apache.struts.actions.IncludeAction.

Il RequestProcessor

Il RequestProcessor è la classe da riscrivere quando si vuole personalizzare il processing dell'ActionServlet.

Essa contiene un entry point predefinito che viene invocato dal controller di Struts con ciascuna richiesta. Questo entry point si chiama processPreprocess().

34

Page 35: HTML Guida Struts

Se si desidera aggiungere il proprio processing specializzato al Controller è necessario implementare il metodo processPreprocess(), aggiungendo la specifica logica e restituendo true per continuare con il processing normale. Se si desidera terminare il processing normale, restituire false per dire al controller che la richiesta corrente è completa.

Ecco un esempio di implementazione di default processPreprocess():

protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { return true;}

Per creare il proprio RequestProcessor è necessario seguire gli step seguenti:

• Creare una classe che estende org.apache.struts.action.RequestProcessor; • Aggiungere un costruttore di default vuoto; • Implementare il metodo processPreprocess()

Ecco di seguito il codice per creare il RequestProcessor:

import javax.servlet.http.*;import javax.servlet.*;import java.io.*;import java.util.*;import org.apache.struts.action.RequestProcessor;

public class EsempioRequestProcessor extends RequestProcessor {

public EsempioRequestProcessor() { } public boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { System.out.println("-------------processPreprocess Logging-------------"); System.out.println("RequestedURI = " + request.getRequestURI()); System.out.println("Protocol = " + request.getProtocol()); System.out.println("Remote Address = " + request.getRemoteAddr()); System.out.println("Remote Host = " + request.getRemoteHost()); System.out.println("Remote User = " + request.getRemoteUser()); System.out.println("Requested Session Id = " + request.getRequestedSessionId()); return true; }}

Nel metodo processPreprocess() reperiamo le informazioni memorizzate in request ed effettuiamo un log.

Una volta che il log è completato, il metodo processPreprocess ritorna il valore boolean true e il processing normale prosegue.

Se il metodo processPreprocess avesse restituito false, il Controller avrebbe terminato il normale processing e l'azione non sarebbe mai stata eseguita.

Per effettuare il deploy del nostro RequestProcessor dobbiamo:

• Compilare il nostro RequestProcessor e metterlo nel classpath dell'applicazione. • Aggiungere l'elemento <controller> al file di configurazione dell'applicazione struts-

35

Page 36: HTML Guida Struts

config.xml.

Ecco il contenuto totale del file struts-config.xml:

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"><struts-config> <form-beans> <form-bean name="lookupForm" type="esempio.LookupForm" /> </form-beans> <action-mappings> <action path="/Lookup" type="fulvios.LookupAction" name="lookupForm" > <forward name="success" path="/quote.jsp" /> <forward name="failure" path="/index.jsp" /> </action> </action-mappings> <controller processorClass="esempio.EsempioRequestProcessor" /> <plug-in className="esempio.EsempioPlugin" /></struts-config>

I Plugin

I Plugin di Struts sono estensioni modulari del controller di Struts. Introdotti con Struts 1.1, sono definiti dall'interfaccia org.apache.struts.action.Plugin. Risultano utili quando si allocano risorse o si preparano connessioni a database o su risorse JNDI.

Questa interfaccia definisce due metodi init() e destroy(), ovvero i metodi del ciclo di vita dei Plugin.

init()Il metodo init() rappresenta l'inizio della vita del plugin: viene invocato quando il container di JSP/Servlet avvia l'applicazione Web contenente il Plugin. Esaminiamone la firma:

public void init(ActionServlet servlet, ApplicationConfig applicationConfig ) throws javax.servlet.ServletException;

Quando viene lanciato, il metodo init() riceve un riferimento all'ActionServlet e all'ApplicationConfig e viene utilizzato per caricare e inizializzare risorse necessarie al Plugin.

Il riferimento ad ActionServlet permette di referenziare le informazioni del Controller mentre l'oggetto ApplicationConfig fornisce l'accesso alle informazioni di configurazione che descrivono l'applicazione Struts.

destroy()Il metodo destroy() termina la vita del Plugin: viene invocato ogni volta che il container di

36

Page 37: HTML Guida Struts

JSP/Servlet arresta l'applicazione Web contenente il Plugin. Questo metodo risulta molto utile perché ci sonsente di rilasciare le risorse allocate dal metodo init(). La sua firma è molto semplice:

public void destroy();

Creare un PluginEcco i passi necessari alla creazione di un Plugin:

• Creare una classe che implementi l'interfaccia org.apache.struts.action.Plugin

• Aggiungere un costruttore di default vuoto • Implementare i metodi init() e destroy() • Compilare il Plugin e spostarlo nel classpath dell'applicazione Web • Aggiungere l'elemento <plug-in> al file struts-config.xml

Ecco un esempio di plugin (Vedi codice completo (http://www.html.it/articoli/2236/cod01.html)):

public void init(ActionServlet servlet, ModuleConfig applicationConfig) throws javax.servlet.ServletException { System.out.println("---->The Plugin is starting<----"); Properties properties = new Properties(); try { File file = new File("c:/info/startup.info"); // Crea l'input stream FileInputStream fis = new FileInputStream(file); // Carica le proprietà properties.load(fis); ServletContext context = servlet.getServletContext(); // ...

L'obiettivo di questo Plugin è quello di rendere disponibili un set di proprietà all'avvio dell'applicazione. Per testarlo non ci resta che:

• Compilare e includere la classe del Plugin nel classpath (spostando il file in una cartella dell'applicazione, nel nostro caso si chiama esempio)

• Aggiungere l'elemento <plug-in> al file di configurazione struts-config.xml • Riavviare l'applicazione.

Ecco come appare il file struts-config.xml:

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"><struts-config> <form-beans> <form-bean name="lookupForm" type="esempio.LookupForm" /> </form-beans>

37

Page 38: HTML Guida Struts

<action-mappings> <action path="/Lookup" type="esempio.LookupAction" name="lookupForm" > <forward name="success" path="/quote.jsp" /> <forward name="failure" path="/index.jsp" /> </action> </action-mappings> <plug-in className="esempio.EsempioPlugin" /></struts-config>

Le taglib di struts

Abbiamo già detto che le viste in Struts sono caratterizzate da pagine Jsp. In questo capitolo esamineremo i vantaggi dell'impiego delle librerie di tag nelle View di Struts. Vedremo i tag più importanti e le loro funzionalità.

Chi conosce linguaggi di markup come XML (http://xml.html.it/guide/leggi/58/guida-xml-di-base/), ha già confidenza con il concetto di tag, qui ricordiamo solo la distinzione tra tag "contenitori" e non.

I tag "senza contenuto" sono quelli che non contengono altri tag, essi specificano l'informazione servendosi solo degli attributi. Sono spesso impiegati per semplici azioni. Un esempio potrebbe essere quello delle immagini in HTML:

<img src="percorso-immagine" />

Gli elementi contenitori invece racchiudono altri elementi o un contenuto tra i tag di apertura e chiusura. L'esempio è quello del paragrafo in HTML:

<p style="text-align:right">Testo allineato a destra</p>

Jsp Custom TagNelle pagine Jsp, oltre al classico markup elaborato direttamente dal browser, è possibile utilizzare il meccanismo dei Custom Tag, ovvero elementi di markup speciali che vengono interpretati dalla nostra applicazione e che, ad esempio, servono a generare automaticamente interi pezzi di markup HTML.

Il rendering e i comportamenti di questi componenti sono affidati ad una specifica classe Java detta tag handler (http://java.html.it/articoli/leggi/2297/custom-tag-jsp-esempio-di-tag-handler/5/). L'handler ha accesso a tutte le risorse della Jsp che ospita i componenti (oggetti session, request, response e pageContext).

Struts mette a disposizione molti tag personalizzati, raggruppati in cinque librerie:

• Html • Bean • Logic • Nested • Template

Le prime versioni di Struts contenevano anche una sesta libreria di tag chiamata form inclusa poi

38

Page 39: HTML Guida Struts

nella libreria Html.

Utilizzare una taglibPer usare le taglib bisogna includere il Tag Library Descriptor (http://java.html.it/articoli/leggi/2297/custom-tag-jsp-definire-un-tag-library-descriptor-tld/3/) (TLD) per ciascuna libreria, che contiene le definizioni di tutti i tag della libreria.

Possiamo farlo grazie alla direttiva <%@taglib%> che ha questa sintassi:

<%@ taglib uri="/WEB-INF/nome_libreria.tld" prefix="prefisso" %>

Dove con l'attributo uri indichiamo il path del file .tld e con prefix indichiamo all'application server che dovrà occuparsi di elaborare tutti i tag che iniziano per "prefisso".

Ad esempio, de vogliamo utilizzare le librerie Html e Bean in una pagina Jsp, inseriamo le seguenti direttive all'inizio della pagina:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

Possiamo trovare un altro semplice esempio qui (http://java.html.it/articoli/leggi/2297/hello-world-con-i-custom-tag-di-jsp/2/).

Nelle lezioni successive vedremo nel dettaglio le librerie e i principali tag che li compongono. Per un riferimento esaustivo su tutti i tag delle librerie di Struts è possibile consultare i javadocs ( http://struts.apache.org/1.x/apidocs/index.html) nella sezione taglib.

La HTML taglib

Una delle librerie di tag più utili di Struts è la HTML taglib: permette di creare form di input e interfacce utente basate su HTML. Il vantaggio nell'utilizzare questi tag sta nel fatto che semplificano l'interazione con il framework, grazie ad essi possiamo ragionare direttamente in termini di action, e concentrarci non tanto sul colloquio tra View e Controller, quanto sulla realizzazione del front end.

Per importare questi tag dobbiamo inserire il relativo riferimento alle definizioni in testa alla nostra vista, con una direttiva simile a questa:

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

In questo caso utilizziamo le definizioni presenti online, ma possiamo anche decidere di utilizzare definizioni salvate in locale sul nostro server.

Tutti i tag di questa libreria saranno richiamati utilizzando il prefisso html: (ad esempio <html:link>)

Facciamo un veloce elenco di questi tag, senza scendere nel dettaglio degli attributi: nelle prossime lezioni esamineremo più dettagliatamente i più importanti.

Tag generici per la formattazione e la navigazioneNome Funzione

39

Page 40: HTML Guida Struts

html Visualizza un elemento html

base Realizza l'elemento base di HTML: definisce in automatico l'indirizzo di base per i link relativi

link Crea il codice HTML per il classico link, ma possiamo sfruttarlo per collegare anche le nostre action, che il framework interpreta come ActionForward

img Visualizza un tag HTML img

frame Definisce un frameset HTML, le pagine vengono chiamate al suo interno con lo stesso meccanismo del tag <html:link>

errors Serve per mostrare messaggi d'errore, ad esempio in caso di validazione di un form

Il tag <html:html>

È usato per la visualizzazione di un elemento HTML. Permette di includere un attributo locale che scriverà le impostazioni locali dell'utente. Un esempio di uso di questo tag è per impostare la lingua dell'applicazione a seconda delle impostazione del browser. Si usa nel seguente modo:

<html:html locale="true"></html:html>

Tag per i formNome Funzione

form Definisce un form HTML

text Casella di testo

password Visualizza un campo di input per le password

textarea Visualizza un campo di input textarea

option Crea un menu a tendina

checkbox Visualizza un campo di input (checkbox)

radio Visualizza un radio button

submit Visualizza un pulsante submit

cancel Crea un campo di input che annulla il form<

reset Visualizza un campo di input con pulsante reset

button Crea un campo di input (pulsante)

file Visualizza un campo di input per la selezione di un file

image Visualizza un tag input del tipo image

hidden Genera un campo nascosto

multibox Mostra un elenco di checkbox

options - optionsCollection Visualizza una raccolta di opzioni select

Il tag <html:form>

Il tag <html:form> di Struts è uno dei più importanti della HTML taglib. Permette di visualizzare un form, che invii i suoi dati riferendosi direttamente ad una action specifica, che potrà servirsi del relativo ActionForm per memorizzare i dati. Esaminiamone gli attributi più importanti:

Nome Funzione

40

Page 41: HTML Guida Struts

action Deve essere dichiarato l'URL (la action) che riceverà i dati da questo form

method Il metodo HTTP per la richiesta

focus Il nome del campo a cui sarà assegnata la priorità nell'esame della pagina

style Lo stile CSS da applicare al form

enctype Esprime la codifica del contenuto da usare quando questo form viene passato all'elaborazione

Gli eventi JavaScriptLa maggior parte dei tag HTML supportano i gestori degli eventi Javascript (event handler) tramite i loro attributi. Sotto l'elenco degli attributi supportati.

Evento Si scatena quandoOnblur l'elemento perde il focus di input

Onclick l'elemento riceve un click del mouse

Onfocus l'elemento riceve il focus

Onkeydown l'elemento ha un focus di input e un tasto è premuto

Onkeypress l'elemento ha un focus di input e un tasto è premuto e rilasciato

onmousemove l'elemento è sotto il puntatore del mouse e il puntatore viene spostato

onmousedown l'emenento viene cliccato

Bean taglib e gestione dei messaggi

Bean taglib e gestione dei messaggiLa Bean taglib è stata creata per permettere alle viste (JSP) di accedere ai JavaBeans e alle proprietà loro associate. Inoltre, grazie a questi tag possiamo definire nuovi bean accessibili all'interno di una pagina attraverso variabili di script e attributi con scope di pagina. Ecco un elenco di alcuni di questi tag:

Tag DescrizioneCookie Permette l'accesso al valore di uno specifico request cookie

Define Definisce una variabile sulla base del valore di uno specifico bean property

Header Definisce una variabile sulla base del valore di uno specifico request header

Include Permette di includere una pagina generata da un'action o ad un URL esterno

page Espone come bean un oggetto dal contesto della pagina specificata

parameter Permette di accedere al valore di un parametro di richiesta

resource Rende disponibile il valore di una risorsa di una web application

Il tag <bean:message>: la gestione dei messaggiIl tag <bean:message>, anche se sembra estraneo alle funzionalità della libreria di tag Bean, è uno dei tag più diffusi di Struts. La sua funzione è quella di prendere un messaggio internazionalizzato per l'area locale del client tramite la Key del messaggio specificata e lo scrive

41

Page 42: HTML Guida Struts

nell'output. Si usa nel seguente modo:

<bean:message key="..."/>

Alcune librerie di Java permettono il supporto della lettura di risorse di messaggi da una classe Java o da un file di proprietà. La classe di partenza è la java.util.ResourceBundle. Struts estende questa funzionalità tramite la org.apache.struts.util.MessagesResources.

Per fissare le idee riprendiamo l'esempio dello struts-blank. La Jsp finale non contiene nessun messaggio ma solo dei tag bean message con le rispettive key:

<bean:message key="welcome.heading"/><bean:message key="welcome.message"/>

I messaggi sono specificati tramite una key nel file message.propeties nel seguente modo:

welcome.heading=Welcome!welcome.message=To get started on your own application, copy the struts-blank.war to a new WAR file using the name for your application. Place it in your container's "webapp" folder (or equivalent), and let your container auto-deploy the application. Edit the skeleton configuration files as needed, restart your container, and you are on your way! (You can find the MessageResources.properties file with this message in the /WEB-INF/src folder.)

Per creare un message resource con struts, basta creare un file .properties nella cartella WEB INF e dichiarare il nome nello struts-config nel seguente modo:

<message-resources parameter="MessageResources" />

Questa funzionalità oltre a suddividere le varie responsabilità ai singoli componenti, risulta molto utile quando vogliamo internazionalizzare la nostra applicazione ma di questo ci occuperemo nelle lezioni successive facendo un esempio.

42