MokaByte 70- Gennaio 2003 
Il Pattern Front Controller
di
S. Rossini
e
L.Dozio

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


Figura 1 - Class Diagram

 


Figura 2 - Sequence Diagram
(clicca per ingrandire)

 

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

 

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it