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 1 - Class Diagram

Class Diagram

Figura 2 - Sequence Diagram
Figura 2 - Sequence 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