jsp-develop.de presents:

Front Controller

von shark,  22.04.2002 16:38:53

JSP-Anwendungen werden in vielen Fällen nach dem von Sun Microsystems (TM) definierten Modell I entwickelt. Bei diesem Anwendungs-typ wird die Geschäfts- und Anzeigelogik direkt in den JSP-Seiten ausprogrammiert.

Die Wartung und Erweiterbarkeit einer Web- Anwendung ist bei diesem Anwendungstyp eingeschränkt, falls sehr vielen JSP-Seiten mit komplexer Geschäftslogik implementiert worden sind. Bei Enterprise JavaBeans (EJB) Anwendungen ist ganz und gar von diesem Ansatz abzuraten, weil "best practices", wie zum Beispiel das Business Delegate Pattern, auf dieser Basis nicht sinnvoll realisiert werden können.

Benutzeranforderungen (Web-Requests) werden dezentral an verschiedenen Stellen mit JSP-Seiten verarbeitet. Fehler in den JSP-Seiten ziehen sich oft durch die komplette Anwendung, weil der Java Source Code nach der Methode "Copy und Paste" über die JSP-Seiten verteilt worden ist.

Abhilfe dieses Dillemas schafft der Front Controller, der konform der von Sun Microsystems spezifizierten Modell II Architektur (Model-View-Controller Konzept) in Web-Anwendungen eingesetzt wird.

Der Front Controller nimmt alle Benutzeranforderungen entgegen und leitet diese an Handler weiter. Die Handler wiederum benutzen Actions (JavaBeans) für den Zugriff auf das Modell einer Web-Anwendung. Im Modell findet die eigentliche Verarbeitung der Benutzeranforderung statt. Oftmals greifen die JavaBeans des Modells, welche die Geschäftslogik enthalten auf relationale Datenbanken via JDBC-API zu, um Datenbankinhalte zu lesen oder zu schreiben.

Nachdem der Geschäftsvorfall im Modell bearbeitet wurde, wird über einen Dispatcher zur View (JSP-Seite) verzweigt, um das Ergebnis der Bearbeitung zu visualisieren. Für den Transport der Daten vom Modell zur View können DTO's (Data Transfer Objects) bzw. Value Objects eingesetzt werden. Wird das Geschäftsmodell in Form von Enterprise JavaBeans (EJB's) umgesetzt, sind DTO's unumgänglich.

Für die Visualisierung der Ergebnisdaten werden in den JSP-Seiten, welche die View repräsentieren, View Helper eingesetzt. View Helper können Tag Libraries bzw. JavaBeans sein, welche die Ausgabe der Ergebnisdaten entsprechend dem gewünschten Layout anzeigen.

Der Front Controller ist Teil des MVC-Konzeptes und entkoppelt die Geschäftslogik einer Anwendung von der Visualisierung in den JSP-Seiten. Aufgrund des zentralen Ansatzes ist die Geschäftslogik nicht mehr über viele JSP-Seiten verteilt. MVC-Anwendungen sind sehr gut erweiterbar und leicht wartbar. Die Definition neuer Handler sowie entsprechender Views erfolgt ausserhalb des Source Codes, sodass sehr schnell auf Änderungen im Geschäftsablauf reagiert werden kann.

Für Enterprise JavaBeans Anwendungen ist es dringend ratsam im Web-Tier einen Front Controller einzusetzen. Benutzeranforderungen
werden dabei direkt über die Handler des Front Controllers zu den Business Delegates dispatched, die das Business Interface des
Service Layers (EJB-Layer) im Application Server referenzieren.

Eine sehr populäre und stabile MVC-Implementierung ist im Jakarta Struts Projekt entwickelt worden. Hinter dem folgenden Link verbergen sich weiterführende Informationen zu dem Framework: http://jakarta.apache.org/struts/

Nachfolgend ein Beispiel für die Anwendung des Frameworks.

Installation von Struts für Tomcat:
------------------------------------------------

- Download des Struts-Frameworks

- Kopieren der struts.jar und jdbc2_0-stdext.jar packages in das
  Tomcat-Lib Verzeichnis

- Kopieren des WEB-Archives: struts-blank.war in das Tomcat-Webapps Verzeichnis

Tomcat führt automatisch das Deployment durch, sodass im Webapps-Verzeichnis ein Verzeichnis struts-blank erzeugt wird, auf dessen Basis man arbeiten kann.

Besser ist es natürlich, nachdem die Web-Anwendung entwickelt ist, wieder ein WEB-Archiv zu erzeugen um dann entsprechend das Deployment von Tomcat durchführen zu lassen.

Nach Abschluss der Installation wird die Struts Applikation folgendermassen ausgeführt: http://localhost:8080/struts-blank

Hat alles geklappt, sollte im Browser ein "Hello World!" erscheinen.


Beispielapplikation (erweitertes struts-blank):
----------------------------------------------------------------

//---------------------------------------
//-- Count JSP-Seite
//---------------------------------------
//-- Addition von zwei Zahlen
//---------------------------------------
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html:html locale="true">
<head>
<title><bean:message key="index.title"/></title>
<html:base/>
</head>
<body bgcolor="white">
<h3><bean:message key="index.heading"/></h3></n>
<b><p><bean:message key="index.message"/></p></b></n>
<html:form action="/count.do">
<html:text property="count1" value="0" size="5" maxlength="5"/>
<p><bean:message key="index.plus"/></p></n>
<html:text property="count2" value="0" size="5" maxlength="5"/>
<html:submit value="Submit"/>
</html:form>
<b><bean:message key="index.result"/></b>  <%= session.getAttribute("Result")%>
</body>
</html:html>


//---------------------------------------
//-- Count Form Objekt
//---------------------------------------
//-- Pruefen der Benutzereingaben
//--
//-- Klassenverzeichnis
//-- \WEB-INF\classes\shark\struts\count
//---------------------------------------
package shark.struts.count;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.actions.*;
import org.apache.struts.action.*;

public class CountForm extends ActionForm
{
  //-- Validate-Methode
  public ActionErrors validate
  (
    ActionMapping      poMapping, 
    HttpServletRequest poRequest 
  )
  {
    ActionErrors loErrors = new ActionErrors();     
   
    //-- Formparameter lesen
    String lstrCount1 = (String) poRequest.getParameter("count1");
    String lstrCount2 = (String) poRequest.getParameter("count2");
   
    int lnCount1 = 0;
    int lnCount2 = 0;
   
    //-- Formparameter konvertieren
    try
    {
      lnCount1 = Integer.parseInt(lstrCount1);
      lnCount2 = Integer.parseInt(lstrCount2);
    }
    catch(NumberFormatException ex)
    {
      loErrors.add("Count", new ActionError("error.count.number_format"));
    }
   
    //-- Formparameter pruefen
    if((lstrCount1.length() < 0)
    || (lstrCount2.length() < 0)
    || (lnCount1 < 0)
    || (lnCount2 < 0))
    {
      loErrors.add("Count", new ActionError("error.count.required"));
    }
   
    return(loErrors);     
  }                             
}

//---------------------------------------
//-- Count Form Action
//---------------------------------------
//-- Addition durchführen
//--
//-- Klassenverzeichnis
//-- \WEB-INF\classes\shark\struts\count
//---------------------------------------
package shark.struts.count;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.actions.*;
import org.apache.struts.action.*;

public class CountAction extends Action
{
  //-- Perform-Methode
  public ActionForward perform 
  (                                   
    ActionMapping      poMapping,       
    ActionForm        poForm,
    HttpServletRequest poRequest,
    HttpServletResponse poResponse
  ) throws IOException, ServletException
  {   
    //-- Formparameter lesen
    String lstrCount1 = (String) poRequest.getParameter("count1");
    String lstrCount2 = (String) poRequest.getParameter("count2");
   
    int lnResult= 0;

    //-- HTTP-Session ermitteln
    HttpSession loSession = poRequest.getSession(true);
   
    //-- Formatkonvertierung und Addition der Eingabewerte
    try
    {
      lnResult = Integer.parseInt(lstrCount1) + Integer.parseInt(lstrCount2);
    }
    catch(NumberFormatException ex)
    {
      ActionErrors loErrors = new ActionErrors();     
      loErrors.add("Count", new ActionError("error.count.number_format"));
    }
   
    //-- Ergebnis in der Session speichern
    loSession.setAttribute("Result", "" + lnResult);
   
    //-- Dispatching zur index.jsp 
    return(poMapping.findForward("result"));     
  }                             
}

<!--
Die Datei - struts-config.xml - liegt im \WEB-INF Verzeichnis und ist entsprechend der WEB-Anwendung anzupassen!
-->
<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">

<struts-config>

  <!-- ========== Form Bean Definitions =================================== -->

  <form-beans>
    <!-- Example logon form bean  -->
    <form-bean name="CountForm" type="shark.struts.count.CountForm"/>
  </form-beans>

  <!-- ========== Global Forward Definitions ============================== -->

  <global-forwards>
    <!-- count forward -->
    <forward  name="result" path="/index.jsp"/>
  </global-forwards>

  <!-- ========== Action Mapping Definitions ============================== -->

  <action-mappings>

    <!-- The standard administrative actions available with Struts -->
    <!-- These would be either omitted or protected by security -->
    <!-- in a real application deployment -->
    <action path="/admin/addFormBean" type="org.apache.struts.actions.AddFormBeanAction"/>
    <action    path="/admin/addForward" type="org.apache.struts.actions.AddForwardAction"/>
    <action path="/admin/addMapping" type="org.apache.struts.actions.AddMappingAction"/>
    <action path="/admin/reload" type="org.apache.struts.actions.ReloadAction"/>
    <action path="/admin/removeFormBean" type="org.apache.struts.actions.RemoveFormBeanAction"/>
    <action path="/admin/removeForward" type="org.apache.struts.actions.RemoveForwardAction"/>
    <action    path="/admin/removeMapping" type="org.apache.struts.actions.RemoveMappingAction"/>

    <!-- Definition der Action fuer die Beispielanwendung --> 
    <action    path="/count"              type="shark.struts.count.CountAction"
              name="CountForm"
              scope="request"
              input="/index.jsp"
              validate="true">
            <forward name="failure" path="/index.jsp"/>
            <forward name="success" path="/index.jsp"/>
    </action>
  </action-mappings>
</struts-config>

<!--
Die Datei - ApplicationResources.properties - liegt im \WEB-INF\classes
Verzeichnis und enthaelt die Textdefinitionen der WEB-Anwendung
-->
index.title= Struts-Beispielapplikation
index.heading= Struts-Beispielapplikation
index.message= Geben Sie bitte zwei Zahlen ein!
index.plus= +
index.result= Ergebnis
URL dieses Beitrags:
http://www.jsp-develop.de/forumbeitrag/view/2011/