Introduzione a Struts

9
JJ — n. 3 — marzo-aprile 2007 Introduzione a Struts di Andrea Colleoni Struts ` e un framework completo e diffuso e offre le basi per sviluppare in modo organico le applicazioni web Andrea Colleoni Andrea Colleoni si oc- cupa professionalmente di sviluppo di software dal 1996 e di Java dal 2000. Attualmente svolge l’attivit ` a di con- sulente attraverso la sua societ ` a, coordi- nando gruppi di lavoro su progetti software di dimensioni medie o grandi in ambito fi- nanziario/bancario e industriale.

description

JJ — n. 3 — marzo-aprile 2007Introduzione a Strutsdi Andrea ColleoniStruts è un framework completo e diffuso e offre le basi per sviluppare in modo organico le applicazioni webAndrea Colleoni Andrea Colleoni si occupa professionalmente di sviluppo di software dal 1996 e di Java dal 2000.

Transcript of Introduzione a Struts

JJ — n. 3 — marzo-aprile 2007

Introduzione a Strutsdi Andrea Colleoni

Struts e un framework completo e diffuso e offre le basi per sviluppare in modo organico leapplicazioni web

Andrea ColleoniAndrea Colleoni si oc-cupa professionalmentedi sviluppo di softwaredal 1996 e di Java dal2000. Attualmentesvolge l’attivita di con-sulente attraverso lasua societa, coordi-nando gruppi di lavorosu progetti softwaredi dimensioni medieo grandi in ambito fi-nanziario/bancarioe industriale.

pubblicato suWWW.INFOMEDIA.IT

!stampa digitale da

Lulu Enterprises Inc.stores.lulu.com/infomedia

InfomediaInfomedia e l’impresa editoriale che da quasi venti an-ni ha raccolto la voce dei programmatori, dei sistemi-sti, dei professionisti, degli studenti, dei ricercatori e deiprofessori d’informatica italiani.Sono piu di 800 gli autori che hanno realizzato per le te-state Computer Programming, Dev, Login, Visual BasicJournal e Java Journal, molte migliaia di articoli tecnici,presentazioni di prodotti, tecnologie, protocolli, strumen-ti di lavoro, tecniche di sviluppo e semplici trucchi e stra-tagemmi. Oltre 6 milioni di copie distribuite, trentamilapagine stampate, fanno di questa impresa la piu grande edinfluente realta dell’editoria specializzata nel campo dellaprogrammazione e della sistemistica.In tutti questi anni le riviste Infomedia hanno vissuto del-la passione di quanti vedono nella programmazione nonsolo la propria professione ma un’attivita vitale e un verodivertimento.Nel 2009, Infomedia e cambiata radicalmente adottandoun nuovo modello aziendale ed editoriale e si e organiz-zata attorno ad una idea di Impresa Sociale di Comunita,partecipata da programmatori e sistemisti, separando leattivita di gestione dell’informazione gestite da un boardcomunitario professionale e quelle di produzione gesti-te da una impresa strumentale. Questo assetto e in lineacon le migliori esperienze internazionali e rende Infome-dia ancora di piu parte della Comunita nazionale deglisviluppatori di software.Infomedia e media-partner di manifestazioni ed eventi inambito informatico, collabora con molti dei piu impor-tanti editori informatici italiani come partner editoriale efornitore di servizi di localizzazione in italiano di testi inlingua inglese.

L’impaginazione automatica di questa rivista e realizzata al100% con strumenti Open Source usando OpenOffice,Emacs, BHL, LaTeX, Gimp, Inkscape e i linguaggi Lisp,Python e BASH

For copyright information about the contents of JavaJournal, please see the section “Copyright” at the endof each article if exists, otherwise ask authors. Infomediacontents is © 2007 Infomedia and released as CreativeCommons 2.5 BY-NC-ND. Turing Club content is© 2007Turing Club released as Creative Commons 2.5 BY-ND.

Le informazioni di copyright sul contenuto di Java Jour-nal sono riportate nella sezione “Copyright” alla fine diciascun articolo o vanno richieste direttamente agli au-tori. Il contenuto Infomedia e © 2007 Infomedia e rila-sciato con Licenza Creative Commons 2.5 BY-NC-ND. Ilcontenuto Turing Club e© 2007 Turing Club e rilasciatocon Licenza Creative Commons 2.5 BY-ND. Si applicanotutte le norme di tutela dei marchi e dei segni distintivi.

E in ogni caso ammessa la riproduzione parziale o tota-le dei testi e delle immagini per scopo didattico purchevengano integralmente citati gli autori e la completaidentificazione della testata.

Manoscritti e foto originali, anche se non pubblicati, nonsi restituiscono.

Contenuto pubblicitario inferiore al 45%.

La biografia dell’autore riportata nell’articolo e sulsito www.infomedia.it e di norma quella disponibi-le nella stampa dell’articolo o aggiornata a cu-ra dell’autore stesso. Per aggiornarla scrivere [email protected] o farlo in autonomia all’indirizzohttp://mags.programmers.net/moduli/biografia

JAVA Journal

47n.3 - marzo/aprile 2007

focus

Introduzione a Struts

Applicazioni Web e Framework: MVC

Le applicazioni web, funzionano tutte seguendo le stesse regole di base e quindi si assomigliano molto fra loro. Pertanto, è nata la necessità per gli sviluppa-tori di queste applicazioni di dotarsi di infrastrutture che costituiscano l’impalcatura generale dell’applica-zione, le fondamenta del progetto: i framework.Parallelamente, gli ingegneri del software hanno in-dividuato che, in linea generale, alcuni problemi che si presentano nell’informatica sono ricorrenti e ben circoscritti; tipologie di problemi ricorrenti hanno tipologie di soluzione altrettanto ricorrenti: i design pattern.MVC (Model View Controller) è un pattern di pro-getto 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 control-ler);

• 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à fun-zionante 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 ed è ospitato nel grande contenitore di progetti che è l’Apache Software Foundation. È reperibile al-l’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:

• Struts Shale Framework; • 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 è necessaria-mente il più valido, ma è oggi uno dei più utilizzati e diffusi. Ha molte estensioni tra cui alcune discreta-mente diffuse: Tiles, di cui non parleremo, è una di queste e fornisce un comodo strumento per costruire la view.

Struts è un framework completo e diffuso e offre le basi per sviluppare in modo organico le applicazioni web

>> di Andrea Colleoni ([email protected])

MVC significa Model-

View-Controller ed è un

pattern molto usato

JAVA Journal

n.3 - marzo/aprile 200748

focus

Download e utilizzo

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 cosidetti “binary”) sia i programmi sorgenti. Nell’archivio struts-x.y.z-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 definizio-ni delle tag library utilizzabili;

• /contrib: contiene un’estensione delle tag library di Stru-ts; non ci occuperemo di questa parte

• /webapps: contiene alcune applicazioni web di esempio che utilizzano Struts, più un’applicazione web utiliz-zabile 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 consul-tare la documentazione e per provare gli esempi di questo articolo avremo bisogno di un servlet container in cui in-stallare le applicazioni.

Essendo le specifiche Servlet e JSP uno standard, qualunque servlet container è adatto, ma in que-st’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 siste-mi operativi. Nei nostri esempi il server è installato sul compu-ter 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 webapp 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 sottodirectory di webapps del

servlet container.Per gli scopi di quest’articolo è necessario installare le se-guenti applicazioni:

• struts-documentation.war • struts-mailreader.war • 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’in-dirizzo

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 ac-count 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.

FIGURA 1 la mailreader demo application

FIGURA 2 la struts console per editare la configurazione

JAVA Journal

n.3 - marzo/aprile 2007 49

focus

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

// web.xml … <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>…

Nella sezione relativa alla definizione dei servlet, viene definito il controller del nostro framework MVC: l’ActionServlet. L’Action-Servlet viene caricato all’avvio e gli vengono passati come parametri due file di configu-razione 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 pattern URL:

// web.xml… <servlet-mapping>

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

Qualunque URL che termini con .do, invoca l’Ac-tionServlet; quindi, a dispetto di quanto possa sembrare a prima vista, non ci sono file “.do” nella webapp.Nella sezione delle Tag Libraries, vengono cari-cate le Tag Libraries di Struts che sono presenti nella cartella WEB-INF.Vediamo il contenuto di una semplice pagina JSP: /index.jsp

<%@ taglib uri=”/tags/struts-logic” prefix=”logic” %><logic:redirect action=”/Welcome”/>

Questo frammento di codice consente di regi-strare l’uso della Tag library struts-logic all’inter-no 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, che è 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 … <action path=”/Welcome” type=”org.apache.struts.webapp.example.WelcomeAction”> <forward name=”failure” path=”/Error.jsp” /> <forward name=”success” path=”/welcome.jsp” /> </action>

LISTATO 1 La JSP per la Logincon struts

// logon.jsp

...

<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>

...

LISTATO 2 La Action (java) per la Login con struts

// LogonAction.java

...

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));

}

...

JAVA Journal

n.3 - marzo/aprile 200750

focus

Questo frammento della configurazione, noto come ActionMapping, fa sì che quando viene richiesta l’URL /Welcome.do (è case sensitive, quindi con la W maiuscola), venga creato un oggetto di classe WelcomeAction, che è istanziato dal fra-mework, 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, rispet-tivamente /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 si ri-ferisce l’action mapping visto sopra, notiamo che l’azione estende una classe fornita nel-l’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 con-figurazione e l’ActionForm. Il metodo quindi termina restituendo al framework che l’ha invocato, un oggetto di tipo ActionForward.

// WelcomeAction.java …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”

FIGURA 3 editiamo una azione

LISTATO 3 un semplice JavaBean

// La classe TextBean è molto semplice: // ha una proprietà di nome text di tipo String // accessibile sia in lettura che in scrittura.

TextBean.javapublic class TextBean { private String text; public String getText() {

return this.text; } public void setText(String text) {

this.text = text; } }

// TextManager ha solo un metodo // che altera il contenuto della // proprietà text del bean TextBean

TextManager.javapublic class TextManager {

public TextManager() { } public void modifica (TextBean tb) { tb.setText(“***” + tb.getText() + “***”); } }

JAVA Journal

n.3 - marzo/aprile 200750

focus JAVA Journal

n.3 - marzo/aprile 2007 51

focus

I metodi findSuccess() e findFailure() sono definiti in BaseAction e facilitano il rintrac-ciamento dei tipici forward success e failure. Nei forward definiti nell’action mapping, vie-ne 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 è governare il flusso dell’applicazione web at-traverso file di configurazione scritti in XML. Il framework offre anche un altro strumen-to 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 (Listato 1).

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

// struts-config.xml … <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 valicato automaticamente dal framework attraverso l’uso del Dy-naValidatorForm) e rappresentato al suo interno come un JavaBean. L’azione /SubmitLogon a cui il form invia le informazioni è così definita:

// struts-config.xml … <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’au-tenticazione utilizzando username e password forniti dal form (Listato 2).

Vale anche la pena di osservare che il metodo execute() è in grado di ritornare alla pagina di logon in caso di errori, con il metodo mapping.getInputForward() che restitui-sce 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 par-tenza.Per interagire con il file di configurazione di Struts, può essere comodo inizialmente utilizzare uno strumento di supporto grafico che aiuti a ricordare la struttu-ra 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 è stata 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 svi-luppo per Java procederemo con lo sviluppo di azioni e pagine JSP.

LISTATO 4 la form che visualizza il bean

// 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>

JAVA Journal

n.3 - marzo/aprile 200752

focus JAVA Journal

n.3 - marzo/aprile 2007 53

focus

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 inse-rire del testo

• All’invio del form tale testo venga trattato da classi di backend e restituito (Figura 4)

Prima di tutto estraiamo con il programma di decompres-sione 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 rappre-sentino il nostro model; costruiamo un JavaBean che rappresenti la nostra informazione ed una classe adatta a trattarlo (Listato 3).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 suc-cessivamente in struts-config.xml (Listato 4).

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 proprie-tà di nome textproperty di tipo String (Figura 2)

• 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 (Figura 3)

• 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: (Listato 5). Per rendere il risultato disponibile alla pagi-na 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.

LISTATO 5 una action per processare il bean

// 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”); }}

Struts funziona su un

application server che

supporta Servlet e JSP

JAVA Journal

n.3 - marzo/aprile 200752

focus JAVA Journal

n.3 - marzo/aprile 2007 53

focus

• Infine aggiungiamo la pagina success.jsp che deve pre-sentare all’utente il risultato del processo avvenuto nel backend (Listato 6).

Per installare ed eseguire l’esempio è necessario compilare il progetto e copiare tutti i file dell’applicazione web conte-nuti nella cartella c:\esempi\struts nel servlet container.Una volta copiati i file necessari navighiamo all’URL http://localhost/struts-blank/text.jsp. A questo punto, basterà inserire del testo nella casella di testo, inviare il form … e avremo ottenuto il risultato atteso.

Conclusioni

Nell’esempio abbiamo toccato i punti essenziali dell’Action Framework che di fatto è l’elemento architetturale che con-sente 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 ap-plicazioni 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 Fra-mework e Shale è conseguenza di questo fatto.

FIGURA 4

LISTATO 6 visualizzare il risultato

// 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>

Note Biografiche

Andrea Colleoni si occupa professionalmente di sviluppo di sof-tware dal 1996 e di Java dal 2000. Attualmente svolge l’attività di consulente attraverso la sua società, coordinando gruppi di lavoro su progetti software di dimensioni medie o grandi in am-bito finanziario/bancario e industriale prevalentemente con tec-nologie legate a J2EE, ma anche con Microsoft.NET. Si occupa anche di formazione; insegna Informatica alla Facoltà di Eco-nomia dell’Università di Bergamo e in altri corsi più specifici organizzati da vari enti di formazione. Vive a Seriate in provin-cia di Bergamo con mia moglie Elena e la sua piccolina, Greta, arrivata cinque mesi fa.