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 RequestProcessor
La 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, 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);
}
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 |
3 | Il 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 |
4 | Quando il metodo RequestProcessor.process() trova una <action> in match, va alla ricerca dell'entry <form-bean> referenziato dall'elemento <action> |
5 | Quando 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 |
6 | Quando i dati dell'ActionForm sono stati caricati, il metodo RequestProcessor.process() chiama il metodo ActionForm.validate() , che controlla la validità dei valori passati |
7 | Il 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'ActionServlet
Come 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>
<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>