9
Introduzione a Struts Andrea Colleoni Applicazioni Web e Framework: MVC Le applicazioni web, funzionano tutte seguendo le stesse regole di base e quindi si assomigliano di più di quanto non differiscano. Per tale motivo è nata la necessità per gli sviluppatori di tali applicazioni di dotarsi di infrastrutture che costituiscano l’impalcatura generale dell’applicazione, le fondamenta del progetto: i framework. Parallelamente gli ingegneri del software hanno individuato che, in linea generale, i tipi di problemi che si presentano nell’informatica sono ricorrenti e non in numero elevato; tipologie di problemi ricorrenti hanno tipologie di soluzione altrettanto ricorrenti: i design pattern. MVC (Model View Controller) è un pattern di progetto che si applica alle applicazioni multi tier, come quelle web, e consiste nella separazione netta tra modello dei dati (il model), controllo del flusso dell’applicazione (il controller) e presentazione dei risultati all’utente (la view). Struts è un framework che aiuta a perseguire la separazione indicata dal pattern MVC e dalla sua evoluzione Model 2, fornendo un controller già funzionante e una base su cui costruire la view. Struts: quando, dove, come e perché; orientarsi nel sito Struts è un progetto sviluppato negli anni dal 2000 al 2001 e ospitato nel grande contenitore di progetti che è l’Apache Software Foundation; è reperibile all’indirizzo http://struts.apache.org/. L’apporto principale al suo sviluppo è venuto da Craig McClanahan già principale fautore del progetto Apache Tomcat ed ora personaggio di spicco nella progettazione di JavaServer Faces dello strato web delle specifiche J2EE. Oggi il popolare framework è diviso in due parti: lo Struts Shale Framework e lo Struts Action Framewok; noi ci occuperemo di quest’ultimo che è l’evoluzione del framework originario. Struts non è un’IDE, non ha un front-end grafico e non costruisce automaticamente applicazioni web; è semplicemente una libreria di oggetti già costruiti che svolgono alcune funzioni di base essenziali per il buon funzionamento di applicazioni web MVC. Struts non è l’unico framework e non è necessariamente il più valido, ma è oggi uno dei più utilizzati e diffusi. Ha molte estensioni tra cui alcune discretamente diffuse; Tiles, di cui non parleremo, è una di queste e fornisce un comodo strumento per costruire la view. Download (versione 1.2.8), contenuto del file ZIP e suo utilizzo Sul sito all’indirizzo http://struts.apache.org/downloads.html sono disponibili per il download sia le release con tutte le librerie compilate e pronte per l’uso (i binaries) sia i programmi sorgenti (i sources). Attualmente la versione più aggiornata disponibile per il download è la 1.2.8.

Introduzione a Struts

Embed Size (px)

DESCRIPTION

Introduzione all'uso di Struts 2.E' il testo integrale di un mio articolo apparso su Java Journal (Infomedia) nel 2007.

Citation preview

Introduzione a Struts

Andrea Colleoni

Applicazioni Web e Framework: MVC

Le applicazioni web, funzionano tutte seguendo le stesse regole di base e quindi si assomigliano di più di quanto non differiscano. Per tale motivo è nata la necessità per gli sviluppatori di tali applicazioni di dotarsi di infrastrutture che costituiscano l’impalcatura generale dell’applicazione, le fondamenta del progetto: i framework.

Parallelamente gli ingegneri del software hanno individuato che, in linea generale, i tipi di problemi che si presentano nell’informatica sono ricorrenti e non in numero elevato; tipologie di problemi ricorrenti hanno tipologie di soluzione altrettanto ricorrenti: i design pattern.

MVC (Model View Controller) è un pattern di progetto che si applica alle applicazioni multi tier, come quelle web, e consiste nella separazione netta tra modello dei dati (il model), controllo del flusso dell’applicazione (il controller) e presentazione dei risultati all’utente (la view).

Struts è un framework che aiuta a perseguire la separazione indicata dal pattern MVC e dalla sua evoluzione Model 2, fornendo un controller già funzionante e una base su cui costruire la view.

Struts: quando, dove, come e perché; orientarsi nel sito

Struts è un progetto sviluppato negli anni dal 2000 al 2001 e ospitato nel grande contenitore di progetti che è l’Apache Software Foundation; è reperibile all’indirizzo

http://struts.apache.org/.

L’apporto principale al suo sviluppo è venuto da Craig McClanahan già principale fautore del progetto Apache Tomcat ed ora personaggio di spicco nella progettazione di JavaServer Faces dello strato web delle specifiche J2EE.

Oggi il popolare framework è diviso in due parti: lo Struts Shale Framework e lo Struts Action Framewok; noi ci occuperemo di quest’ultimo che è l’evoluzione del framework originario.

Struts non è un’IDE, non ha un front-end grafico e non costruisce automaticamente applicazioni web; è semplicemente una libreria di oggetti già costruiti che svolgono alcune funzioni di base essenziali per il buon funzionamento di applicazioni web MVC.

Struts non è l’unico framework e non è necessariamente il più valido, ma è oggi uno dei più utilizzati e diffusi. Ha molte estensioni tra cui alcune discretamente diffuse; Tiles, di cui non parleremo, è una di queste e fornisce un comodo strumento per costruire la view.

Download (versione 1.2.8), contenuto del file ZIP e suo utilizzo

Sul sito all’indirizzo http://struts.apache.org/downloads.html sono disponibili per il download sia le release con tutte le librerie compilate e pronte per l’uso (i binaries) sia i programmi sorgenti (i sources). Attualmente la versione più aggiornata disponibile per il download è la 1.2.8.

Nell’archivio struts-1.2.8-bin.zip (oppure tar.gz) contenente le librerie compilate, troviamo le seguenti cartelle:

/lib: contiene tutti i file JAR necessari a far funzionare le varie parti del framework, più tutte le DTD e le definizioni delle tag libraries utilizzabili

/contrib: contiene un’estensione delle tag libraries di Struts; non ci occuperemo di questa parte

/webapps: contiene alcune applicazioni web di esempio che utilizzano Struts, più un’applicazione web utilizzabile come base di partenza per costruire applicazioni basate su Struts e la documentazione su Struts e Tiles

Per far funzionare le applicazioni di esempio, per consultare la documentazione e per provare gli esempi di questo articolo avremo bisogno di un servlet container in cui installare le applicazioni.

Essendo le specifiche Servlet e JSP uno standard, qualunque servlet container è adatto, ma in quest’articolo ci riferiremo sempre al server Apache Tomcat versione 5.x, reperibile all’indirizzo http://tomcat.apache.org/ e di cui sono disponibili gli installer per Windows o gli archivi compressi, contenenti i file per l’installazione su tutti i sistemi operativi.

Nei nostri esempi il server è installato sul computer locale (localhost) e sulla porta http di default (80) per cui gli indirizzi saranno nella forma http://localhost/struts-examples/welcome.do.

L’installazione delle webapps fornite con Struts può avvenire copiando i file .WAR nella directory webapps del servlet container, eseguendone un upload dal pannello di amministrazione del servlet container oppure estraendone i file con un programma per la gestione di file compressi tipo WinZip in una directory sotto webapps del servlet container.

Per gli scopi di quest’articolo è necessario installare le applicazioni struts-documentation.war, struts-mailreader.war e struts-blank.war.

Uno sguardo alle applicazioni di esempio

Struts viene fornito con alcune applicazioni di esempio tra cui struts-mailreader. Esplorando il contenuto all’indirizzo http://localhost/struts-mailreader/Welcome.do, si accede ad una semplice applicazione di registrazione di informazioni; tramite un form è possibile registrare un utente, per il quale possono poi essere definiti alcuni account di accesso a server di posta. Una volta registrato, un utente, può rieseguire l’accesso e visualizzare l’elenco degli account definiti. I dati vengono conservati in un database XML nel file WEB-INF/database.xml.

Dando un’occhiata più in profondità, cerchiamo di capire come funziona e quale plus dà Struts a questa applicazione. In primo luogo osserviamo il descrittore WEB-INF/web.xml:

Nella sezione relativa alla definizione dei servlet, viene definito il controller del nostro framework MVC: l’ActionServlet.

web.xml (frammento)

<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, /WEB-INF/struts-config-registration.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

L’ActionServlet viene caricato all’avvio e gli vengono passati come parametri due file di configurazione scritti in XML che il servlet caricherà all’avvio dell’applicazione e di cui vedremo tra poco il contenuto.

Per essere invocato dal servlet container, l’ActionServlet, deve essere associato ad un URL pattern:

web.xml (frammento)

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

Qualunque URL che termini con .do, invoca l’ActionServlet, quindi a dispetto di quanto possa sembrare a prima vista, non ci sono file “.do” nella webapp.

Nella sezione delle Tag Libraries, vengono caricate le Tag Libraries di Struts che sono presenti nella cartella WEB-INF.

Vediamo il contenuto di una semplice pagina JSP: /index.jsp

index.jsp

<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

<logic:redirect action="/Welcome"/>

Questo frammento di codice consente di registrare l’uso della Tag library struts-logic all’interno della pagina JSP e quindi di utilizzare il tag redirect di tale libreria per eseguire un’azione di redirect. In particolare il browser viene rediretto verso una Action di nome Welcome, la quale è definita nel file di configurazione di Struts.

Nella sezione action-mappings del file WEB-INF/struts-config.xml, viene definita tra le altre l’azione Welcome:

struts-config.xml (frammento)

<action path="/Welcome"

type="org.apache.struts.webapp.example.WelcomeAction">

<forward name="failure" path="/Error.jsp" />

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

</action>

Questo frammento della configurazione, che viene chiamato ActionMapping, fa sì che quando viene richiesto l’URL /Welcome.do (è case sensitive, quindi con la W maiuscola), venga creato un oggetto di classe WelcomeAction, che è istanziato dal framework, ma definito dal programmatore.

Il frammento contiene anche la definizione di due forward di nome failure e success. A questi sono associate due pagine JSP, rispettivamente /Error.jsp e /welcome.jsp.

Vediamo cosa significano queste impostazioni e come funziona un’azione Struts.

Aprendo il file WEB-INF/src/org/apache/struts/webapp/example/WelcomeAction.java, a cui l’action mapping visto sopra si riferisce, notiamo che l’azione estende una classe fornita nell’esempio: BaseAction che a sua volta estende la classe del framework Action introducendo rispetto a quest’ultima solo alcuni semplici metodi di utilità.

Una volta individuata la classe corrispondente all’azione, il framework la istanzia e ne invoca il metodo execute() al quale vengono passati tutti gli oggetti per operare con il contesto web e due oggetti Struts: l’ActionMapping che rappresenta il contenuto del file di configurazione e l’ActionForm. Il metodo quindi termina restituendo al framework che l’ha invocato, un oggetto di tipo ActionForward.

WelcomeAction.java (frammento)

public final class WelcomeAction extends BaseAction {

public ActionForward execute(

ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception {

...

if (messages.size()>0) {

...

return findFailure(mapping);

}

return findSuccess(mapping);

}

}

Nel codice, a seconda del successo o meno di alcune istruzioni che non è nostro scopo approfondire, possiamo decidere di “uscire con successo” o “uscire con insuccesso” dal metodo.

I metodi findSuccess() e findFailure() sono definiti in BaseAction e facilitano il rintracciamento dei tipici forward success e failure. Nei forward definiti nell’action mapping, viene definito cosa fare in caso di successo e cosa in caso di insuccesso.

In caso di successo, nel nostro esempio, viene caricata nel browser la “view” /welcome.jsp che è la pagina che si vede navigando l’URL http://localhost/struts-mailreader/Welcome.do, che chiude gli elementi del paradigma MVC.

In definitiva uno dei compiti del controller è quello di governare il flusso dell’applicazione web attraverso file di configurazione scritti in XML.

Il framework offre anche un altro strumento configurabile molto utile: l’ActionForm. Nel file di configurazione, notiamo che c’è un’azione /Logon.do che fa semplicemente un forward alla pagina /logon.jsp.

<action path="/Logon"

forward="/logon.jsp"/>

La pagina /logon.jsp, contiene un form costruito con i tag della libreria HTML di Struts:

logon.jsp (frammento)

<html:form action="/SubmitLogon" focus="username"

onsubmit="return validateLogonForm(this);">

...

<html:text property="username" size="16" maxlength="18"/>

...

<html:password property="password" size="16" maxlength="18"

redisplay="false"/>

...

<html:submit property="Submit" value="Submit"/>

...

<html:reset/>

...

</html:form>

Anche nel file di configurazione di Struts esiste una rappresentazione di questo form; si trova nella sezione form-beans:

struts-config.xml (frammento)

<form-bean name="LogonForm"

type="org.apache.struts.validator.DynaValidatorForm">

<form-property name="username" type="java.lang.String"/>

<form-property name="password" type="java.lang.String"/>

</form-bean>

Il contenuto del form può essere quindi gestito dal framework (in questo caso viene addirittura validato automaticamente dal framework attraverso l’uso del DynaValidatorForm) e rappresentato al suo interno come un JavaBean. L’azione /SubmitLogon a cui il form invia le informazioni è così definita:

struts-config.xml (frammento)

<action path="/SubmitLogon"

type="org.apache.struts.webapp.example.LogonAction"

name="LogonForm"

scope="request"

input="logon">

...

</action>

La classe LogonAction conterrà il codice per eseguire l’autenticazione utilizzando username e password forniti dal form:

LogonAction.java (frammento)

public ActionForward execute(...) throws Exception {

...

String username = (String) PropertyUtils.getSimpleProperty(form,

USERNAME);

String password = (String) PropertyUtils.getSimpleProperty(form,

PASSWORD);

...

return (mapping.getInputForward());

...

return (findSuccess(mapping));

}

Vale la pena di osservare anche che il metodo execute() è in grado di ritornare alla pagina di logon in caso di errori, con il metodo mapping.getInputForward() che restuisce il forward definito nell’attributo input dell’action-mapping.

Uno sguardo alla "blank application"

La “blank-application” è contenuta nell’archivio struts-blank.war e contiene lo “scheletro” di un’applicazione web che funziona con il controller Struts. Ha un web.xml che carica l’ActionServlet con la configurazione definita nel file struts-config.xml, che inizialmente contiene alcuni esempi ben commentati.

Per iniziare a costruire applicazione web con Struts la blank-application fornisce quindi una buona base di partenza.

Per interagire con il file di configurazione di Struts, può essere comodo inizialmente utilizzare uno strumento di supporto grafico che aiuti a ricordare la struttura del file e il suo utilizzo. Un buono strumento in tal senso è la Struts console reperibile all’indirizzo http://www.jamesholmes.com/struts/console/ di cui in questo esempio è stat usata la versione 4.8.

Per iniziare con una nuova applicazione, quindi estrarremo il file struts-blank.war in qualche directory nella quale verranno costruiti tutti i percorsi e i file di default, quindi usando la console struts e un kit di sviluppo per Java procederemo con lo sviluppo di azioni e pagine JSP.

Costruzione di un semplice esempio

Proviamo ora a costruire, partendo dalla blank.application, un’applicazione web che svolga i seguenti compiti:

Da una pagina /text.jsp venga offerta la possibilità di inserire del testo

All’invio del form tale testo venga trattato da classi di back end e restituito

Prima di tutto estraiamo con il programma di decompressione il file struts-blank.war in una cartella, ad esempio c:\esempi\struts. Poi con un editor Java creiamo secondo la struttura delle applicazioni web, le classi che rappresentino il nostro model; costruiamo un JavaBean che rappresenti la nostra informazione ed una classe adatta a trattarlo:

TextBean.java

public class TextBean {

private String text;

public String getText() {

return this.text;

}

public void setText(String text) {

this.text = text;

}

}

La classe TextBean è molto semplice: ha una proprietà di nome text di

tipo String accessibile sia in lettura che in scrittura.

TextManager.java

public class TextManager {

public TextManager() {

}

public void modifica (TextBean tb) {

tb.setText("***" + tb.getText() + "***");

}

}

TextManager ha solo un metodo che altera il contenuto della proprietà

text del bean TextBean

Servlet Container

Browser

WebApplication

text.jsp

success.jsp

ActionServlet

struts-config.xml

Action

Model

Creiamo quindi un semplice form usando la libreria HTML di Struts al posto dei normali tag HTML; il form avrà come action l’azione /SubmitAction che andremo a definire successivamente in struts-config.xml:

text.jsp

<%@ taglib uri="/tags/struts-html" prefix="html" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Form</title>

</head>

<body>

<html:form action="/SubmitAction">

Testo: <html:text property="textproperty" /><br />

<html:submit />

</html:form>

</body>

</html>

Usiamo la struts console per costruire il form e mappare l’azione; dal menù file apriamo il file struts-config.xml che abbiamo estratto in c:\esempi\struts\WEB-INF ed eseguiamo i seguenti passi:

Aggiungiamo un form bean di nome textform e di tipo DynaActionForm ed a questo aggiungiamo una proprietà di nome textproperty di tipo String

Ora aggiungiamo un’action-mapping con URL /SubmitAction che usi il form bean che abbiamo appena creato; il tipo di mapping deve essere SubmitAction che è il nome della classe che andremo a creare fra poco per gestire l’azione:

Aggiungiamo nella configurazione del mapping anche un forward che chiameremo success che punti al path /success.jsp:

Possiamo salvare lo struts-config.xml, chiudere la struts console e prosegure con l’editor Java

Ora dobbiamo costruire la nostra classe SubmitAction che preso il valore inserito nel form lo manipola con le classi del model e lo restituisce alla pagina /success.jsp:

SubmitAction.java

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.action.ActionForm;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.PropertyUtils;

public class SubmitAction extends Action {

public ActionForward execute(

ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response) throws Exception {

ActionForward retValue;

TextBean tb = new TextBean();

TextManager tm = new TextManager();

tb.setText((String) PropertyUtils.getSimpleProperty(form, "textproperty"));

tm.modifica(tb);

request.setAttribute("risultato", tb);

return mapping.findForward("success"); }

}

Per rendere il risultato disponibile alla pagina view, una tecnica

utilizzata è quella di valorizzare un attributo dell’oggetto request,

il quale poi verrà letto con la libreria di tag di Struts bean.

Infine aggiungiamo la pagina success.jsp che deve presentare all’utente il risultato del processo avvenuto nel back-end:

Success.jsp

<%@ taglib uri="/tags/struts-bean" prefix="bean" %>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>JSP Page</title>

</head>

<body>

Il testo contenuto nel JavaBean processato è <bean:write name="risultato" property="text" />

</body>

</html>

Accediamo con il tag bean:write ad un bean che si chiami risultato e

quindi ne scriviamo la proprietà text. Da notare il fatto che accediamo

a text nel bean e non più textproperty del form.

Per installare ed eseguire l’esempio è necessario compilare il progetto e copiare tutti i file dell’applicazione web contenuti nella cartella c:\esempi\struts nel servlet container.

Una volta copiati i file necessari navighiamo all’URL http://localhost/struts-blank/text.jsp.

Inseriamo del testo nella casella di testo

Inviamo il form ed avremo il risultato:

Conclusioni e bibliografia

Nell’esempio abbiamo toccato i punti essenziali dell’Action Framework che di fatto è l’elemento architetturale che consente di scrivere applicazioni web secondo il paradigma MVC.

Struts in effetti è un framework completo e diffuso e offre anche basi per sviluppare organicamente altre parti delle applicazioni web, come il supporto all’internazionalizzazione, alla validazione che in quest’articolo abbiamo solo sfiorato.

L’avvento di altri validi framework di successo ed il tentativo di standardizzare lo sviluppo di applicazioni MVC condizionano lo sviluppo di Struts ed in effetti la divisione tra l’Action Framework e Shale è conseguenza di questo fatto.