Contesto
Il livello di presentazione si deve occupare di realizzare un meccanismo di controllo, coordinamento e gestione delle richieste utente il più possibile univoco ed uniforme. Il meccanismo può essere gestito sia in modo centralizzato che decentralizzato.
Intento
L'intento del pattern è quello di rappresentare l'unico punto di ingresso del sistema (Presentation Layer), in grado di gestire in modo univoco le richieste che giungono da invocazioni http. Il pattern garantisce:
- Gestione uniforme del Presentation
- Gestione della navigazione nel sistema
- Selezione della vista
- Sicurezza (autenticazione, autorizzazione, tracciamento dell'utente, ecc...)
- Mantenimento dello stato dell'applicazione
- Gestione della sessione utente
- Tracciamento mediante Log
- Gestione della messaggistica tramite I18n e l10n
Motivazione
Il pattern rappresenta il punto centrale d'ingresso dell'architettura e concentra in un unico punto le operazioni di controllo, gestione e dispatching. Questo garantisce uno sviluppo più organico ed uniforme del progetto, migliorando manutenibilità e riuso del codice.
Spiegazione del funzionamento
Il Front Controller è una classe che si occupa di gestire le richieste del client delegando la specifica gestione dell'azione ad opportune classi Helper (dette RequestHandler - gestore della richiesta).
All'arrivo della richiesta HTTP, il FrontController effettua le operazioni di verifica della coerenza dell'ambiente (Sessioni, Autenticazione della richiesta, Autorizzazione, tracciamento utente) e poi richiama la classe opportuna per la gestione della richiesta. Una volta innescato e concluso il processo di elaborazione, il controller si occupa di aggiornare il modello dati (Presentation Model) a fronte di modifiche che l'operazione appena eseguita ha apportato al Business Model, e di invocare la vista successiva.
Struttura
Il Front Controller, in ambito J2EE, è implementato con una Servlet (Servlet Front Strategy) o mediante pagina JSP (JSP Front Strategy).
Class Diagram
Sequence Diagram
Un caso d'uso
Si riporta una FrontControllerServlet che rappresenta il punto d'ingresso di un'applicazione Web e che si occupa di:
- istanziare ed eseguire il RequestHandler opportuno legato alla funzionalità richiesta dall'utente attraverso il parametro FUNCTION
- gestione della sessione HTTP
- log della richiesta
- inizializzazione i18n
- configurazione della HTTP response
- selezione della prossima vista da invocare
- gestione in caso di eccezione da parte del RequestHandler
public class FrontControllerServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String function = null;
String risorsa = null;
HttpSession session = null;
try {
function = request.getParameter("FUNCTION");
verifica la validità della sessione HTTP
// Check HTTP Session
if(function.equals("LOGIN")) { session = request.getSession(true);}
else{ session = request.getSession(false);}
if (session == null) {
throw new InvalidSessioneException(". . .");
}
effettua il trace della funzione richiesta e dei dati del richiedente
// Perform trace
this.log(new java.util.Date().toString() + " : function[" + function +
"] required by " +
request.getRemoteUser()+ "-" + request.getRemoteAddr());
effettua la gestione dell'internazionalizzazione
// i18n managing
if(session.getAttribute("LANGUAGE") == null){
session.setAttribute("LANGUAGE",DEFAULT_LANGUAGE);
}
istanzia l'handler associato all'azione richiesta
GenericRequestHandler grh =
FactoryRequestHandler.getRequestHandler(function);
lo inizializza e lo manda in esecuzione
grh.init(session);
grh.execute(request, response, context);
richiede la successiva risorsa
risorsa = grh.getPageName();
effettua la configurazione della risponse HTTP
response.setContentType("text/html");
//disabilita cache del browser-HTTP 1.0
response.setHeader("Pragma","No-cache");
//previene caching da parte del proxy server
response.setDateHeader("Expires", 0);
//disabilita cache del browser-HTTP 1.01
response.setHeader("Cache-Control","no-cache");
se si è avuta un'eccezione nella gestione della richiesta viene creato l'error view bean con la descrizione dell'eccezione, e selezionata la view d'errore (nell'es. la pagina error.jsp)
} catch (RequestHandlerException ex) {
risorsa = "/jsp/error/error.jsp";
request.setAttribute("ErrorMessage",ex.getMessage());
ex.printStackTrace();
}
ed inoltra la richiesta alla prossima risorsa selezionata dall'handler
RequestDispatcher rd =
this.getServletContext().getRequestDispatcher(risorsa);
rd.forward(request, response);
}
Bibliografia e riferimenti
- [FACADE] S.Rossini, L. Dozio - "J2EE Patterns - Il pattern facade", Mokabyte N.64 Giugno
- [Gof] Gamma, Helm, Johnson, Vlissides :
Design Patterns - Elements of Reusable Object-Oriented Software
- [J2EE] Alur,Crupi,Malks :
Core J2EE Patterns - Best Practices and Design Strategies
- [SJP] Sun Java Center J2EE Patterns:
http://developer.java.sun.com/developer/restricted/patterns/J2EEPatternsAtAGlance.html
- [BPP] Sun blueprints-Design Patterns Catalog :
http://java.sun.com/blueprints/patterns/j2ee_patterns/catalog.html
