Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring...

42
Programmazione Java Avanzata Struts Struts Ing. Gianluca Caminiti

Transcript of Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring...

Page 1: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Programmazione Java

Avanzata

StrutsStruts

Ing. Gianluca Caminiti

Page 2: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Riferimenti

� Struts2 in Action, Manning 2008.

(Capitoli da 1 a 3 per la parte introduttiva)

(Capitolo 4 per gli interceptor)

(Capitolo 5 per OGNL)

� Documentazione ufficiale di Struts

http://struts.apache.org/

Page 3: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts MVC

Page 4: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts MVC

� Controller: FilterDispatcher

� Model: Action

� View: Result

Page 5: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts MVC (Dettaglio)

Page 6: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Definizioni

� Interceptors: permettono di realizzare compiti

trasversali all’applicazione.

� ValueStack: Area di memorizzazione per tutti i dati

che sono utilizzati nel ciclo di vita di una request.

� OGNL: Linguaggio usato per leggere / scrivere /

manipolare dati presenti nel ValueStack.

Page 7: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example1

� Uso del Convention plug-in:

� Per default, esso cerca le classi che rappresentano le action

nei package struts, struts2, action o actions. In questo caso

il package è com.caminiti.action.

� La classe action deve implementare l’interfaccia

com.opensymphony.xwork2.Action oppure il nome della

classe deve terminare con Action. Noi deriviamo la classe

WelcomeUser dalla classe

com.opensymphony.xwork2.ActionSupport che implementa

l’interfaccia com.opensymphony.xwork2.Action.

Page 8: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example1

� Il plug-in usa il nome della classe per mappare la URL corrispondente all’azione. Quindi da WelcomeUser si ottiene la URL welcome-user. Il plugin effettua la conversione automaticamente per ottenere la URL associata.

� Ora il plug-in conosce quale classe invocare per una specifica richiesta. Il prossimo passo è trovare il result a cui cedere il controllo. Questo si fa sulla base del valore restituito dal metodo execute(). Per default il plug-in cerca nella directory WEB-INF/

� Per scegliere il nome del file, il plug-in si basa sul valore restituito dalla classe action. Se è restituito “success”, esso cercherà un nome di file del tipo: welcome-user-success.jsp oppure welcome-user.jsp.

Page 9: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example2

� Esempio di uso delle annotazioni:

� L’annotazione @Action serve per cambiare la

convenzione sull’associazione di default. La classe

WelcomeUserAction per defalut sarebbe stata

associata dal plug-in all’URL welcome-user (la

parola Action è rimossa e il “cammello” (…eUs…)

è trasformato in un trattino).

� Con @Action si specifica che la classe

WelcomeUserAction è associata all’URL welcome.

Page 10: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example2

� Il file struts.properties è usato per cambiare il comportamento di default per i result, che sarebbero cercati nella cartella WEB-INF/content.

� Per fare in modo che i result siano cercati nella cartella WebContent/results si deve impostare la proprietàstruts.convention.result.path=/results

� A questo punto il plug-in cercherà nella cartella specificata il file welcome.jsp come view di default, in base al fatto che la classe action invocata era stata associata alla URL welcome.

� Per specificare un nome di file che sostituisca quello di default, si usa l’annotazione @Result.

Page 11: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example3

� Esempio di uso del file di configurazione

struts.xml

� Nota: deve essere presente nella cartella WEB-

INF/classes (notare che Eclipse non la genera per

default) o meglio, nella root dei sorgenti (src in

Eclipse – Usare il Navigator view)

Page 12: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example4UI

� Esempio di form con auto-popolamento e

associazione con gli oggetti Java

� Esempio di uso degli UI tags

Page 13: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example5DT

� Esempio di uso dei Data Tags per accedere al

ValueStack: property, set, push.

Page 14: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example6BT

� Esempio di uso dei Data Tags per accedere al

ValueStack: bean tag.

Page 15: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example7CT

� Esempio di uso dei Control Tags per accedere al ValueStack: Iterator, If/Else.

Name Return Type Description

index int zero-based index value.

count int index + 1

first boolean returns true if it is the first element

last boolean returns true if it is the last element

even boolean returns true if the count is an even number.

odd boolean returns true if the count is an odd number.

modulus int takes an int value and returns the modulus of count.

Page 16: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example8OGNL

� Esempio di gestione di array e collections con

OGNL.

� Esempio di invocazione di metodi di action.

Page 17: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Conversioni di Tipo

� String

� boolean/Boolean

� char/Character

� int/Integer, float/Float, double/Double, long/Long

� Date (es. 31/12/2010)

� array

� List

� Map

Page 18: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example9Interc

� Esempio di logging con interceptor

Page 19: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Interceptors (Cap. 4 Manning)

� Il framework selezione la classe Action da invocare per una data request e individua gli interceptor associati a tale azione.

� Il framework crea un’istanza di ActionInvocation ed esegue il suo metodo invoke().

� ActionInvocation incapsula l’azione e gli interceptor associati.

� Action invocation conosce in che ordine gli interceptordovrebbero essere invocati e chiama il metodo intercept() corrispondente al primo interceptor nello stack.

Page 20: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Il metodo intercept()

public String intercept(ActionInvocation invocation)

throws Exception

{

//Pre processing

logMessage(invocation, START_MESSAGE);

String result = invocation.invoke();

//Post processing

logMessage(invocation, FINISH_MESSAGE);

return result;

}

Page 21: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Il metodo intercept()

� Preprocessing - All’inizio è invocato il metodo logMessage(), che stampa un messaggio.

� Dopo, è eseguito il metodo invoke() sull’oggettoActionInvocation. Questa invocazione determina la chiamata del prossimo interceptor (corrisponde ad una chiamata ricorsiva).

� Tale ciclo proseguirà finchè tutti gli interceptor sullo stack saranno chiamati.

� Dopo l’esecuzione dell’ultimo interceptor, la classe Action saràinvocata.

� Infine, gli intercettori saranno richiamati in senso inverso. Poi una stringa result sarà restituita e la view corrispondente saràresa all’utente.

Page 22: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Il metodo intercept()

� Nel caso di un errore di validazione, l’elaborazione della

richiesta sarà interrotta. Nessun altro interceptor saràchiamato. L’Action non sarà eseguita.

� Il flusso di controllo cambierà in modo tale che gli

intercettori fino ad allora invocati siano richiamati, ma in ordine inverso, in accordo alla chiamata ricorsiva.

� Al termine, sarà visualizzata all’utente una certa view, a seconda del result restituito.

Page 23: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example10Interc

� Esempio di modifica allo stack di default

� Per default il metodo validate sarebbe invocato

sia prima del metodo populate che prima del

metodo execute.

� Vogliamo alterare il comportamento di default

inibendo la chiamata di validate prima di

populate.

Page 24: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example10Interc

� Modo alternativo per modificare lo stack.<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<package name="default" extends="struts-default">

<action name="*Sample" method="{1}" class=“caminiti.SampleAction">

<interceptor-ref name="defaultStack" >

<param name="validation.excludeMethods"> populate</param>

</interceptor-ref>

<result name="populate">/first.jsp</result>

<result name="success">/success.jsp</result>

</action>

</package>

</struts>

Page 25: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example11-12MA

� Esempi che mostrano l’uso di azioni multiple.

Page 26: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example13-

14Validation

� Esempi che mostrano come convalidare i dati di

un form.

� Riferimenti: Manning, cap.3

Page 27: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example15

� Esempio che mostra il funzionamento dell’interceptor params.

� L’object domain (user) è automaticamente inizializzato dal framework.

� Notare che se nella Action mancano i getter ed i setter per il domainobject, il passaggio di parametri con il ValueStack non è possibile.

� Il framework è sincrono alla classe java per quanto attiene al model object, cioè se nella classe si cambia il riferimento al model object nel metodo execute(), anche il result JSP si riferirà a tale oggetto.

� Uso implicito del validator: provare a mettere nel form dei dati non validi (es. type mismatch su “age”….)

Page 28: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example16

� Esempio che mostra il funzionamento dell’interceptor modelDriven e della omonima interfaccia.

� L'interfaccia permette di riferirsi direttamente ai campi dell'oggetto restituito dal metodo getModel().

� Questa tecnica si aggiunge a quella classica, ma non la sostituisce, per cui ad es. il nome dell’utente è accessibile sia mediante “user.name”che attraverso “name” (in questo ultimo caso perché l’oggetto user èrestituito dal metodo getModel()).

� Il motivo di quanto sopra è dovuto al fatto che il metodo getModel()pone l’oggetto “user” sulla cima del ValueStack.

� Attenzione: se si cambia il riferimento del model object, il framework e la classe java non sono più in sincronia (E’ sufficiente evitare di fare puntare il riferimento altrove, p.es. con new…).

Page 29: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example15-16

� Nota sul trasferimento di dati:

poiché i dati contenuti nella request (il cui nome è uguale a

campi della Action) sono trasferiti in automatico nei campi

corrispondenti, è possibile fare una injection su tali campi.

� Nel caso dell’esempio 16 si possono usare come parametri

sia user.age che age (per la presenza di modelDriven), ad

es., per sovrascrivere l’età dell’utente.

� Riferimenti:

Manning, cap. 3, 4, e 5.1

Page 30: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example17

� Uso di FileUploadInterceptor

� E’ un interceptor di default, tuttavia vediamo in che modo è possibile specificare le proprietà nel file XML.

� Il tipo di encoding usato nel form DEVE essere multipart/form-data per rendere possibile l’upload.

� Notare le convenzioni usate per i nomi dei campi contentType e fileName, che dipendono dal nome del campo associato al file.

Page 31: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example18

� Uso di FileUploadInterceptor

� Esempio completo che mostra come gestire upload

multipli e salvare tali file sul server.

� I file contenenti le proprietà di default si trovano in:

struts2-core,

org.apache.struts2, *.properties

Page 32: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example19Spring

� Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin(struts2-spring-plugin-2.1.6.jar)

� Tutti gli oggetti creati dal framework sono istanziati dalla ObjectFactory, che fornisce il modo di integrare Struts con container IoC come Spring o altri.

� Questo plug-in funziona mediante overriding della ObjectFactory di Struts, per permettere la creazione di Action, Interceptors e Result da parte di Spring. Spring interviene solo quando lo specifichiamo.

� Quando un oggetto è creato il plugin usa l’attributo class nel file di configurazione di Struts per trovare una corrispondenza con l’attributo id usato nella configurazione di Spring.

� Riferimenti: Manning cap.9

Page 33: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example20Hiber

� Uso di Struts2 con Hibernate mediante il plugin Full Hibernate Plugin GA (http://code.google.com/p/full-hibernate-plugin-for-struts2/)

� Hibernate Validator integration – (vedere esempio successivo)

� Hibernate Core Sessions injection - Fornisce un Interceptor che apre e imposta nel ValueStack una Session di Hibernate e poi la chiude dopo che i risultati sono restituiti al client (@SessionTarget).

� Riferimenti: http://community.jboss.org/wiki/OpenSessioninView

� Hibernate Transactions injection - Un Interceptor che apre e imposta nel ValueStack una Transazione e fa il commit dopo che i risultati sono resi al client, oppure rollback in caso di errore (@TransactionTarget).

� Hibernate Core configuration management Web Tool¶

Page 34: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example20Hiber

� Affinchè si possa effettuare l’injection per sessioni e transazioni, glioggetti Session e Transaction devono essere dichiarati come campi diclasse e non di metodo.

� Ad es., si possono mettere queste variabili in una classe DAO genericae poi estendere tale classe.

� Il metodo "transaction.rollback()“ dovrebe essere usato solo in metodiche aggiornano il DB.

Page 35: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example21Hiber

� Uso di Struts2 con Hibernate + Hibernate

validator

� Riferimenti:http://docs.jboss.org/hibernate/stable/validator/reference/en/html/validator-

usingvalidator.html

� Approccio DRY (Don’t Repeat Yourself!)

� Vincoli di base predefiniti: @Length(min=, max=), @Max(value=),

@Min(value=), @NotNull, @NotEmpty, etc.

Page 36: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example21Hiber

� Gli interceptor stack introdotti dal plugin

� basicStackHibernate: Struts2 basickStack + Hibernate session and

transaction capability.

� defaultStackHibernate: Struts2 defaultStack (no validations) +

Hibernate validation, session and transaction capability.

� defaultStackHibernateStrutsValidation: Struts2 defaultStack (with

validation) + basicStackHibernate.

Page 37: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example22Hiber

� Uso di Struts2 con Hibernate per operazioni

CRUD

� Esempio in cui si vede come gestire opportunamente la mancanza di

sincronia fra il model object (passato da Java con modelDriven) e il

framework.

� Il tag push è usato nel form in register.jsp per spostare l’oggetto user

condiviso con la Action sulla cima del ValueStack.

� Il form serve sia per inserire che per aggiornare. Durante l’inserimento

la proprietà user si riferisce al model object User esposto

dall’interfaccia ModelDriven. In questo caso il tag push è ridondante e

non sarebbe necessario.

Page 38: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example22Hiber

� Tuttavia il form serve anche per aggiornare. In questo caso la proprietà user si riferisce al campo user del JavaBean che è restituito dal metodo listUserById().

� Adesso il tag push sarà utile perché spinge sulla cima del ValueStackl’oggetto User corrispondente, permettendoci di evitare l’uso di espressioni OGNL di secondo livello come user.name per accedere alle proprietà dell’oggetto di dominio.

� In questo modo l’oggetto user recuperato da listUserById() diventa l’oggetto corrente e quando si sceglie Submit esso non sarà aggiunto con una nuova id, ma sarà aggiornato l’oggetto stesso.

� Il tag url è usato per creare una nuova URL che è quella della Action corrispondente al metodo inteso (edit/delete). Assieme a tale URL sipassa un parametro id ed il corrispondente valore effettivo (con il tag param).

� Si usa l’espressione OGNL "%{}" come sequenza di escape per riferirsi al valore assunto nell’ActionContext.

Page 39: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example23

� Spring+Struts2+Hibernate

� Esempio che parte dal precedente, aggiungendo

Spring per sfruttare la DI.

� Notare come cambia il comportamento

dell’applicazione se il bean user è singleton (default)

o prototype (che è la scelta giusta in questo caso).

Page 40: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example23

� Bean scopes in Spring� singleton – Crea una singola istanza per ogni IoC container di Spring

� prototype – Crea una nuova istanza ogni volta che è richiesto

� request – Crea una singola istanza per ogni richiesta HTTP

� session - Crea una singola istanza per ogni sessione HTTP

� globalSession – Crea una singola istanza comune a tutte le sessioni

dell’applicazione

Page 41: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example23

Singleton

Page 42: Programmazione Java Avanzata Struts - unirc.it · 2011-08-03 · Uso di Struts2 come MVC con Spring per usare Dependency Injection, mediante il struts2-spring-plugin (struts2-spring-plugin-2.1.6.jar)

Struts2Example23

Prototype