Struts 1.x Tutorial

Folgendes Tutorial soll als Hilfe für alle dienen die sich mit dem Java basierten Struts Webframework beschäftigen wollen. Das Tutorial ist schon etwas älter und bezieht sich auf Struts in Version 1.x. Aber viele der hier vorgestellten Themen können 1:1 auf Struts 2.x angewandt werden. Dies gilt insbesondere für die Tiles Taglib in Abschnitt 5.4.

Zunächst möchte ich eine kurze Einleitung dazu geben was das STRUTS Open Source Web Application Framework genau ist und wie es entstand. In den darauffolgenden Kapiteln gehe ich dann näher auf die API dieses Frameworks ein und versuche seine Mächtigkeit und Flexibilität mit einigen Beispielen zu untermauern.

Einleitung

Durch das STRUTS Open Source Web Application Framework wird die Entwicklung von Java basierenden Webanwendungen nicht nur stark vereinfacht, sondern es ermöglicht auch die komfortable Möglichkeit der Wiederverwendbarkeit von Code und dessen einfache Pflege und Erweiterung.

Es basiert auf bereits vorhandenen und in der Praxis bewährten Javatechnologien wie Java Server Pages, Java Servets, XML und Resource Bundles. Besonderns durch letztere Technologie wird die Implementierung von Mehrsprachigkeit in Webanwendungen zum Kinderspiel. Man spricht in diesem Zusammenhang auch von Internationalisierung (i18n). Das Framework wurde im Jahre 2000 der Apache Software Foundation hinzugefügt und untersteht dem Jakarta Projekt.

Über das weitverbreitete Dispatcher-Konzept wird das MVC Pattern implementiert, das die Prsentationsschicht (View) von den Daten (Model) trennt und über die Logik (Controller) verbindet. STRUTS ist auch für größerer Projekte sinnvoll, solange man das gesamte Framework als reines Frontend betrachtet und die eigentliche Arbeit in tiefere Schichten verschiebt.

Das Framework in der Version 1.1 bietet ein paar Vorteile gegenüber seiner Vorgngerversion. So besteht in Version 1.1 die Möglichkeit Tiles zu definieren. Diese bieten
die Möglichkeit erweiterter Templates mit denen eine weitere Modularisierung von Webanwendungen und deren komfortable Konfiguration ber XML möglich ist. Ein gute Hilfe zu Struts findet man auch in der offiziellen Dokumentation zu Struts [Str 2004].

Schichtenmodell

Eine sauber implementierte Anwendung zeichnet sich unter anderem dadurch aus, dass die Darstellung der Daten für den Benutzer von der Businesslogik unabhängig ist und bleibt. Im Falle von STRUTS muss also gewährleistet sein, dass die Businesslogik nicht von STRUTS abhängt, da andernfalls eine Trennung der Schichten nicht mehr gewährleistet werden kann. Bei den Schichten handelt es sich um logische und evt. sogar physisch gruppierte Softwarekomponenten, die gemeinsam einen bestimmten Zweck erfüllen. Eine J2EE Anwendung kann in folgende drei Schichten unterteilt werden.

Präsentationsschicht

Zur Präsentationsschicht zählen alle Klassen und anderen Komponenten die für die Darstellung der Daten (View) zuständig sind. Gelingt es diese Schicht frei von jedweder Businesslogik zu halten spricht man von einem Thin-Client oder sogar Ultra-Thin-Client. Neben marketingpolitischen Aspekten eines Thin-Clients spricht auch dessen Flexibilität für selbigen.

Das STRUTS Framework befindet sich komplett in dieser Schicht und sollte die Businesslogik der Anwendung lediglich benutzen, nicht jedoch implementieren! &Auuml;nderungswünsche von Kunden beziehen sich meist auf die Oberfläche und aus diesem Grund ist auf die Trennung der Schichten zu achten. Kommt es zu einem &Auuml;nderungswunsch an der Oberfläche der Anwendung mssen nur noch die Komponenten der View angepasst werden, nicht jedoch die Komponenten der anderen Schichten. Durch voneinander unabhängige Schichten entstehen bei der Entwicklung und anschließenden Pflege somit enorme Zeitersparnisse, da ein erneutes Deployment und Testen der Komponenten anderer Schichten entfällt. Eine Abhängigkeit der View von der Businesslogikschicht ist
natürlich immer gegeben, nur anders herum muss es vermieden werden.

Businesslogiksicht

Die Businesslogikschicht ist die Schicht mit dem größten Entwicklungsaufwand. Hier werden die Anforderungen des Kunden fachlich umgesetzt. Hier gilt natürlich, dass eine Abhängigkeit von der Prsentationsschicht auszuschließen ist. Eine Abhängigkeit von der Integrationsschicht ist allerdings nicht vollkommen möglich, da deren Daten in der Businesslogik zur Verarbeitung benötigt werden. Für die Kommunikation zwischen Businesslogik und Präsentationsschicht ist eine robuste Schnittstelle zu definieren, die sich auch bei einer neuen Version der Anwendung nicht ändert. Dadurch wird es möglich, dass mehrere Teams unabhängig voneinander an den verschiedenen Schichten arbeiten können.

Integrationsschicht

Diese Schicht stellt die Daten bereit die in der Businesslogikschicht benötigt werden und nimmt deren verarbeiteten Daten entgegen. Hauptaufgabe dieser Schicht ist die Bereitstellung verschiedener Dienste wie etwa der Anbindung an eine Datenbank. Die Integrationsschicht ist zudem für das STRUTS Framework völlig transparent.

MVC-Pattern

Das MVC Pattern – MVC steht als Akronym für Model View Controller und trennt die Zuständigkeiten bei Oberflächen in drei Bereiche auf:

Abbildung 3.1: Model View Control

Abbildung 3.1: Model View Control

  • Das Model ist das Geschäftsmodell oder Business-Objekte.
  • Eine View ist für eine jeweilige Darstellung verantwortlich, also dafür, die Informationen aus den jeweiligen Models dem Benutzer anzuzeigen und ihm eine weitere Benutzerführung zu bieten.
  • Die Controller sind das Bindeglied zwischen alledem. Sie nehmen Aktionen seitens der Oberfläche (Events wie Mausklicks und HTTP Requests) entgegen, arbeiten auf dem Model und geben die verarbeiteten Daten an eine nächste View weiter.

Die View präsentiert das Model, wobei ein Model mehrere Views haben kann. Ein vereinfachtes Beispiel: Eine digitale oder analoge Anzeige der Geschwindigkeit in einem Auto. Beide Anzeigen sind mögliche Views des Models Geschwindigkeit. Durch Verwendung des MVC-Patterns können die Oberflächen problemlos ausgetauscht werden, was für J2EE Anwendungen immens wichtig ist. Eine professionelle Webanwendung wie beispielsweise ein Internetportal kann es sich nicht leisten seine User immer mit dem gleichen Design zu überraschen. Statt dessen werden die Webseiten in Richtung besserer Benutzerfreundlichkeit und verbesserter Optik getrimmt. Dies ist nur durch eine Trennung von View und Model möglich, da hier der Entwicklungsaufwand für eine neue Oberfläche minimiert wird. Die View greift also über eine Schnittstelle auf die Daten des Models zu und stellt diese dar. Von einer Änderung der Oberfläche bleibt das Model gänzlich unberührt.

Elemente des STRUTS Frameworks

ActionForms

Die Arbeit mit Formularen in STRUTS ist wahrscheinlich die angenehmste Eigenschaft dieses Frameworks, denn die Benutzereingaben können vom Framework automatisch validiert werden. Außerdem werden die Formularinhalte in JavaBeans gekapselt und sind so über mehrere Seitenaufrufe hinweg gespeichert. Beispiel Onlineshop.

Es wäre aus psychologischen Grnden nicht sinnvoll den Käufer erst dazu zu zwingen sich als Kunde zu registrieren und dann erst etwas in seinen Warenkorb legen zu können. Statt dessen kauft er erst mal in Ruhe ein und wenn er bezahlen will, wird von der Anwendung festgestellt, dass er weder registriert noch angemeldet ist. Also gelangt er automatisch zu der Seite wo er seine personenbezogenen Angaben machen muss. Zu diesem Zeitpunkt hat der Benutzer aber schon mehrere Formulare ausgefüllt, z.B. Artikel und Bestellmengen. Im Normalfall wären diese Eingaben verloren, aber da STRUTS wie schon gesagt alle Formulareingaben in Beans speichert, gelangt der Benutzer nach der Registrierung zu seinem Bestellformular zurück und alle Eingaben stehen noch da.

Für jedes Formular muss eine JavaBean geschrieben werden. Stellen wir uns ein klassisches Login Formular vor. Es besteht aus 2 Eingabefeldern – einem für den Benutzernamen und einem für das Passwort. Wir brauchen also eine JavaBean mit 2 Variablen die diese Eingaben speichert. Zu beachten ist auch das es bei einem Loginformular nicht erwünscht ist, dass das Passwort stehen bleibt, sondern nur der Benutzername, da sonst ein anderer Benutzer des Computers das Passwort kopieren und missbrauchen könnte. Zu diesem Zweck muss also noch eine reset() Methode implementiert werden. Diese Methode muss zum einen aus der Actionklasse die das Formular verarbeitet aufgerufen werden und wird außerdem dann aufgerufen, wenn der Resetbutton (Falls im Formular vorhanden) betätigt wird. Diese JavaBean muss außerdem von org.apache.struts.action.ActionForm erben.

Hier nun ein Beispiel für so eine ActionForm.

package myPackage.forms
import org.apache.struts.actions.*;

import javax.servlet.http.*;
public class LoginForm extends ActionForm
{
  private String login;

  private String password;
  public void reset(ActionMapping mapping, HttpServletRequest request)
  {
    password="";
  }
  public String getLogin()
  {
    return login;
  }
  public String getPassword()
  {
    return password;
  }

  public void setLogin(String login)
  {
    this.login=login;
  }

  public void setPassword(String password)
  {
    this.password=password;
  }
}
Ein Loginformular mit ActionForm

Validierung

Formulare können automatisch validiert werden. Kommt es bei der Validierung zu Fehlern werden diese in einem ActionErrors Objekt gespeichert, in den Request Scope gelegt und die Seite wo die Eingabe erfolgt ist erneut aufgerufen. Auf dieser können die Fehler dann angezeigt werden. Als Passwörter in unserem eben genannten Beispiel könnten zum Beispiel nur Zahlen gültig sein. Gibt der Benutzer im Passwortfeld einen Buchstaben ein, so soll er darauf hingewiesen werden. Unsere ActionForm muss dazu um die Methode validate() erweitert werden:

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
{
  ActionErrors errors = new ActionErrors()
  try
  {
    int password = Integer.parseInt(this.getPassword());
  }
  catch (NumberFormatException e)
  {
    errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.password.notNumber"));
  }
  return errors;
}
Validierung von Benutzeringaben mit validate()

error.password.notNumer ist dabei ein Key aus den Ressourcen. Diese ActionForm Klasse muss dem Framework nun noch mitgeteilt werden.

Actions

Die Actions sind wie bereits deutlich wurde ein zentraler Bestandteil des Frameworks. Es handelt sich dabei um Javaklassen die dem Framework in der struts-config.xml bekannt gemacht werden müssen. Unser Benutzer aus dem vorigen Beispiel ist angemeldet und möchte die Webseite verlassen. Zu diesem Zweck muss er sich abmelden, denn sonst könnte jemand der Zugang zu dem Computer hat seine aktuelle Session übernehmen und missbrauchen. Der Benutzer muss also auf einen Äbmelden“ Link klicken. Was passiert danach? Die Session des Benutzers muss einfach nur zerstört werden. Damit werden dann alle temporren Benutzereingaben gelöscht, da diese an die Session gebunden sind. Actionklassen erben von org.apache.struts.action.Action und implementieren die execute() Methode. Wir nennen diese Klasse LogoutAction und machen diese STRUTS in der struts-config.xml bekannt:

<action-mappings>
  <action path="/logout" type="myPackage.actions.LogoutAction"/>
</action-mappings>
Registrierung der LogoutAction in der struts-config.xml

Die Klasse würde dann folglich so aussehen:

package myPackage.actions;

import org.apache.struts.action.*;
import javax.servlet.http.*;

public class LogoutActon extends Action
{
  public ActionForward execute(ActionMapping mapping, 
                                              ActionForm form, 
                                              HttpServletRequest req, 
                                              HttpServletResponse res)
  {
    HttpSession session = req.getSession(false);
    try
    {
      session.invalidate();		
    }
    catch (Exception e){}
    return mapping.findForward("start_page");
  }
}
LogoutAction mit org.apache.struts.action.Action

Zuerst holen wir uns die Session aus dem Request und zerstören sie anschließend mit der invalidate() Methode. Dabei kann es zu einem Fehler kommen und zwar dann wenn die Session bereits abgelaufen ist und folglich nicht zerstört werden kann. Diesen Fehler können wir aber ignorieren, denn im Anschluss machen wir sowieso ein Forward zur Startseite. Angenommen unsere Action müsste Formulardaten verarbeiten und würde nicht zum Abmelden, sondern zum Anmelden dienen. Dazu würden wir uns der LoginForm bedienen die weiter oben bereits besprochen wurde. In der execute() Methode müssen wir dann ActionForm f nach LoginForm casten wie Abbildung zeigt.

LoginForm loginForm = (LoginForm)form;
Zugriff auf Daten einer ActionForm in einer Action

Über die set und get Methoden aus der LoginForm können wir nun auf die Benutzereingaben reagieren und zum Beispiel eine Datenbankabfrage starten um den Nutzer zu authentifizieren.

ForwardAction

Das direkte Verlinken von eine JSP Seite zu einer anderen soll auf jeden Fall vermieden werden, da sonst das MVC-Prinzip verwässert und untergraben wird. Die STRUTS Klasse ForwardAction bietet hierfür die komfortable Möglichkeit zu einer JSP Seite oder anderen Ressource weiterzuleiten und die Steuerung bleibt im Controller. Diese Actions sind auch deshalb sehr einfach und unkompliziert, weil man dafür keine Zeile Javacode schreiben muss. Statt dessen wird die ForwardAction nur in der struts-config.xml definiert:

<action path="/start" type="org.apache.struts.actions.ForwardAction" parameter="/welcome.jsp"/>
Definition einer ForwardAction in der struts-config.xml

Die STRUTS Tag Libraries

Tags sind Formatierungselemente in Dokumenten die von einem Client zur Darstellung von Daten benutzt werden. Zu solchen Dokumenten gehören beispielsweise HTML und JSP Seiten. Darüber hinaus gibt es Tags die im Server zur logischen Formatierung der Daten benutzt werden und in HTML Tags transformiert werden. Das STRUTS Framework stellt in verschiedenen Libraries solche Formatierungselemente bereit. Weiterhin erlauben beispielsweise die Tags aus der BEAN-Library den Zugriff auf die Daten des Models. Die STRUTS Tag Libraries hatten zudem einen großen Einfluss auf die neue JSP Taglib JSTL.

Ein großer Vorteil dieser Tags besteht darin, dass eine Entwicklung von JSP Seiten ohne Scripting möglich ist. Dadurch ist nicht nur der Sourcecode solcher Seiten besser lesbar und damit besser wartbar, es ist auch für Webdesigner ohne Programmierkenntnisse möglich dynamische Seiten zu entwickeln und zu gestalten. Die Tag Libraries tragen außerdem dazu bei eine Verwässerung des MVC Konzepts zu verhindern, da Programmierer erfahrungsgemäß dazu geneigt sind Teile der Businesslogik in den JSP Seiten (View) zu implementieren. STRUTS bietet folgende Tag Libraries:

  • HTML: Erweiterung der HTML Tags
  • LOGIC: Logische Komponenten wie Iterationen
  • BEAN: Zugriff auf Beans (Daten des Models)
  • TILES: Tags für STRUTS Tiles

An dieser Stelle möchte ich ein kleines Beispiel zeigen, dass die Verwendung und den Nutzen dieser Tags verdeutlichen soll: Angenommen eine Liste aller Kunden einer Datenbank soll im Browser dargestellt werden. Die einzelnen Kundendatensätze werden in der Businesslogik in Objekten der Klasse Kunde gekapselt. Die Klasse Kunde sähe dann zum Beispiel aus wie in Abbildung:

public class Kunde
{
  private String name;
  private String ort;

  public String getName()
  {
    return name;
  }

  public String getOrt()
  {
    return ort;
  }

  public void setName(String name)
  {
    this.name=name;
  }

  public void setOrt(String ort)
  {
    this.ort=ort;
  }
}
Sourcecode der Klasse Kunde

Gespeichert werden die einzelnen Kundenobjekte in einer Bean vom Typ Collection.

[...]
Kunde kunde;
Collection kundenBean = new ArrayList();
while(resultSet.next())
{
  kunde = new Kunde();
  kunde.setName(resultSet.getString(1));
  kunde.setOrt(resultSet.getString(2));
  kundenBean.add(kunde);
}
[...]
Sourcecode zum Fllen der Collection

Die Bean steht also unter dem Namen kundenBean den JSP Seiten zur Verfügung und beinhaltet Objekte vom Type Kunde. Nachfolgend der Code zur Anzeige der Kunden wie er aussehen würde, wenn nur die Standart JSP Tags verwendet würden.

[...]
<table>
<% java.util.Iterator iterator = kundenBean.iterator();
  while (iterator.hasNext())
  {
    Kunde kunde = (Kunde)iterator.next();
%>
<tr>
  <td>
    <%=kunde.getName()%>
  </td>
  <td>
    <%=kunde.getOrt()%>
  </td>
</tr>
<% } %>
</table>
[...]
Iteration mit Standart JSP

Dieser Ansatz hat die Konsequenz, dass die JSP Seite unübersichtlich, damit schwer wartbar und fehleranfällig ist. Mit den STRUTS Tag Libraries wird dieses Problem eindeutig behoben, wie nachfolgender Code zeigt.

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>

<table>
  <logic:iterate id="kunde" name="kundenBean">
    <tr>
      <td><bean:write name="kunde" property="name"/></td>
      <td><bean:write name="kunde" property="ort"/></td>
    </tr>
  </logic:iterate>
</table>
Iteration mit der STRUTS Taglib

Der Code ist jetzt sehr übersichtlich und kann auch von einem Designer ohne Programmierkenntnisse verstanden und selbst entwickelt werden.

Die HTML Taglib

Die HTML Taglib unterstützt den Entwickler bei der Erzeugung von HTML basierten GUI’s. Die STRUTS HTML Tags spielen besonders im Zusammenhang mit Formularen eine große Rolle. Mit ihnen ist es aber auch möglich die Fehlermeldungen die beim Validieren der Benutzereingaben auftreten dem Benutzer anzuzeigen sowie kontextrelative Links zu generieren die nicht nur auf statische HTML Seiten verweisen können, sondern auch auf Actions und globale Forwards die in der struts-config.xml definiert sind. An dieser Stelle möchte ich ein paar der wichtigsten Tags aus dieser Bibliothek erläutern.

Das <html:form/> Tag

Das <html:form/> Tag erzeugt ein HTML <form/> Element. Diese Form ist dann an eine Formbean (ActionForm sup>10) gebunden. Alle Eingabefelder im Formular stehen dabei in Verbindung mit entsprechenden Klassenattributen in der Formbean. Diese Verbindung entsteht durch die Angabe der hinter dieser Form stehenden Action, welche genau wie die Formbean in der struts-config.xml angegeben werden müssen. Ein kleines Beispiel: Ein Eingabeformular soll dazu dienen einen neuen Benutzer der Website zu registrieren. Benötigt wird dafür unter anderem der Name des Benutzers. Die Eingabe des Namens erfolgt über ein <html:text/> Field. Dieses Tag erzeugt ein HTML Input field vom Typ text. Dieses Tag benötigt einen Parameter, der die Verbindung zur Formbean herstellt, in unserem Fall also den Parameter „name“: <html:text name=“name“/>.

In der Formbean gibt es dann eine Klassenvariable vom Typ String die den Namen speichert und die entsprechenden set und get Methoden. Die Methoden in diesem Fall heißen dann setName(String name) und getName(). Wichtig dabei ist zu beachten, dass die Nomenklatur beachtet wird. In der JSP Seite wird dann als Parameter für das <html:text/> Tag der Parameter ,,name“ übergeben und nicht „Name“! Für das <html:form/> Tag muss noch der Parameter angegeben werden der die Verbindung zur Actionklasse herstellt. Der Name des Parameters entspricht wiederum einer Definition in der struts-config.xml und aus dieser Definition folgt wiederum welche Formbean zur Verarbeitung der Daten genutzt wird. Für unser Beispiel würde eine Definition in der struts-config.xml wie folgt aussehen:

<struts-config>
  <form-beans>
    <form-bean name="RegisterForm" type="myPackage.forms.RegisterForm"/>
  </form-beans>

  <action-mappings>
    <action path="/register" type="myPackage.actions.RegisterAction" name="RegisterForm"/>
  </action-mappings>
</struts-config>
Registrierung der Form
Workflow in STRUTS

Workflow in STRUTS

Der Ablauf der Verarbeitung wird in folgender Abbildung verdeutlicht.

  1. Der Client (Browser) stellt eine Anfrage an eine STRUTS Action. Dies geschieht entweder durch das Absenden eines Formulars, oder durch den direkten Aufruf durch einen Link wie z.B. /myAction.do
  2. Das Suffix .do ist ein Actionmapping welches in der web.xml von Tomcat definiert wird und signalisiert Tomcat, dass es sich um eine STRUTS Action handelt welcher diesen Request dann an das STRUTS Action Servlet weiterleitet.
  3. Die Daten aus dem Request werden vom ActionServlet aus dem Request herausgeholt und daraus ein Action-Form Objekt generiert.
  4. Nach erfolgreicher Validierung (optional)
  5. wird die definierte Action aufgerufen und die ActionForm als Parameter der execute() Methode mitgeliefert. Diese Daten werden jetzt von der Action und anderen Models (z.B. EJB’s) verarbeitet (z.B. speichern in einer Datenbank). Zum Schluss wird dann ein ActionForward an das ActionServlet zurückgegeben. Dieses Forwardziel entspricht einer Definition der globalen Forwards in der struts-config.xml.
  6. Das ActionServlet nimmt den Namen des ActionForwards, sucht anhand dessen Namens die entsprechende JSP Seite aus der struts-config.xml und schickt diese Seite an den Client.
  7. Der Client zeigt die JSP Seite an. Durch die Action (Punkt 5) wurden eventuell auch Beans gespeichert, deren Daten nun angezeigt werden können.

Für unser Beispiel bedeutet das folgendes: Das input Feld mit dem Parameter „name“ enthält den Namen des Benutzers. Dieser Wert wird in der Formbean für die ganze Dauer der Session gespeichert. Wird zu einem späteren Zeitpunkt die Seite zur Benutzerregistrierung nochmals aufgerufen steht der zuvor eingegebene Wert immer noch in dem Feld. Dies gilt auch, wenn eine Validierung (Punkt 4) einen Fehler erzeugt hat (z.B. falsche Eingabe des Namens, des Geburtstages, oder der Emailadresse). In diesem Fall speichert das ActionServlet die Fehler bei der Validierung im Request, welche dann in der JSP Seite ber <html:errors/> ausgegeben werden können.

Das <html:errors/> Tag

Wie schon erwähnt können Fehler die bei der Validierung der Benutzereingaben in Punkt 4 aufgetreten sind über dieses Tag ausgegeben werden. Im einfachsten Fall gibt <html:errors/> alle Fehler die bei der Validierung aufgetreten sind nacheinander aus. Es gibt aber auch die Möglichkeit Fehler für bestimmte Eingabefelder anzeigen zu lassen. Dies ist zum Beispiel dann sinnvoll, wenn der Übersichtlichkeit halber die Fehler direkt ber dem betroffenen Feld ausgegeben werden sollen. Dazu wird das Tag einfach durch den optionalen Parameter „property“ ergänzt. Ein Beispiel: Ein Benutzer hat im Feld fr die Emailadresse eine falsche Adresse eingegeben (z.B. Fehlendes @ Zeichen oder keine Domain wie .de usw.). dieses Eingabefeld hat den Namen ëmail“. Der Code in der JSP Seite könnte etwa so aussehen:

[...]
<font color="#FF0000"><html:errors property="email"/></font>
<html:text name="email"/>
[...]
Beispielcode für das <html:errors/> Tag

Bei einer falschen Eingabe der Benutzeradresse z.B. fehlendes @ Zeichen könnte die Fehlermeldung dazu wie folgt aussehen:

Falsche Benutzereingabe mit Hinweis

Falsche Benutzereingabe mit Hinweis durch <html:errors/>

Weitere Form Elemente

Für das Erstellen von Formularen stehen eine reihe verschiedener Tags zur Verfügung die eine dynamische Generierung von HTML Form Elementen erlauben. Mit <html:select/> können Listen erzeugt werden. Inhalte dieser Listen sind Option Felder die entweder einzeln mit <html:option/> erzeugt werden, oder dynamisch mit <html:options/> und <html:optionsCollection/>.

Bei letzteren beiden werden die Einträge für die Liste aus einer Bean heraus generiert. Die Bean wiederum kann diese Daten zur Laufzeit erzeugen, oder aus einer Datenbank gewinnen. Mit <html:checkbox/> werden wie sich vermuten lässt Checkboxen erzeugt und mit <html:radio/> Radioboxen die in Gruppen erzeugt und nur einzeln selektierbar sind.

Das <html:link/> Tag

Es kommt sehr oft vor, dass Links ber URL Rewriting modifiziert werden müssen. Dass ist zum Beispiel dann der Fall, wenn der Client keine Cookies annimmt in denen die Keys für die Session gespeichert werden können. In diesem Fall muss der Session Key als ID an die URL angehangen werden. Das <html:link/> Tag erledigt dies automatisch. Über weitere (optionale) Parameter können weitere Parameter an die URL und somit dem Request angehangen werden. Tabelle listet alle wichtigen Attribute für das Tag. Wenn möglich sollte statt „page“ immer „forward“ zum Verlinken interner Seiten genutzt werden. Dies dient der Übersichtlichkeit der Anwendung, da jegliche Grundkonfiguration des Workflows in der struts-config.xml vorgenommen wird.

Die Bean Taglib

JavaBeans sind die im Kapitel beschriebenen Schnittstellen mit denen JSP Seiten (Die View) auf die Daten des Models zugreifen. Sie sind also das Bindeglied zwischen JSP Seiten und der in den Actions (Controller) enthaltenen Businesslogik. Die STRUTS Bean Taglib bietet Möglichkeiten um auf diese Beans zuzugreifen.

Das <bean:define/> Tag

Beans werden wie der STRUTS Workflow auf Seite pageref zeigt in den Actions entweder an die Session des Benutzers, oder an den Request gebunden. Um die Daten der Beans zu verwenden müssen diese in der JSP zur Verwendung definiert werden. Dabei wird einer Bean eine Scriptingvariable zugewiesen, über die an anderen Stellen im Code auf diese Bean zugegriffen werden kann. In Anlehnung an das Beispiel aus Kapitel könnte eine solche Definition wie folgt aussehen.

<bean:define id="user" name="userBean"/>
Beispiel<bean:define/>

„id“ bezeichnet dabei die Scriptingvaraibale und „name“ den Namen der Bean der ihr in der Action gegeben wurde.

Das <bean:write/> Tag

Mit diesem Tag können Daten aus einer Bean im Browser ausgegeben werden. Angenommen die Bean mit dem Benutzer hat also den Namen üserBean“ und wir wollen die Emailadresse des Benutzers ausgeben, dann sähe der Code wie folgt aus:

<bean:write name="user" property="email"/>
Beispielcodedas <bean:write/> Tag

Voraussetzung ist allerdings, dass die zugehörige Methode in der JavaBean die den Zugriff auf die Emailadresse erlaubt getEmail() heit. Das Attribut „name“ gibt dabei den Namen der Scriptingvariablen an, unter der die Bean ansprechbar ist. „property“ spezialisiert das Property der Bean welches ausgegeben werden soll. Angenommen es besteht eine Klasse ContactInformation in derjeden Benutzer Anschrift, Telefonnummer, Emailadresse usw. gespeichert werden sollen. Über getContactInformation() in der userBean wird ein Objekt dieser Klasse zurückgegeben. In ContactInformation wiederum gibt es eine getEmail() Methode um die Emailadresse zurückzugeben, dann erfolgt der Zugiff auf die Emailadresse über die Userbean wie folgt.

<bean:write name="user" property="contactInformation.email"/>
<bean:write/> mit indiziertem Zugriff

Das <bean:message/> Tag

Wie bereits erwähnt ist STRUTS die ideale Voraussetzung um internationalisierte Webanwendungen zu entwickeln. Eine Grund dafür ist in der Verwendung dieses Tags zu suchen. Damit dies möglich wird, muss zunächst für jede zu unterstützende Sprache eine Ressourcendatei angegeben werden. Diese liegt in einem beliebigem Package der Anwendung, z.B. myPackage.ressources. Diese Dateien haben die Endung .properties. Darauf zu achten ist, dass alle Ressourcendateiendie unterschiedlichen Ländern den selben Namensstamm haben. Dieser lautet gewöhnlich ApplicationRessources. Dieser wird zunächst in der struts-config.xml angegeben.

<message-resources parameter="myPackage.resources.ApplicationResources"/>
Ressourcenkonfiguration in der struts-config.xml

Es muss unbedingt eine Datei mit dem Namen ApplicationResources.properties geben! Abhängig von der eingestellten Locale des Benutzers wird die Message in der entsprechenden Ressource für dieses Land/Sprache gesucht. Gibt es für dieses Land keine eigene Ressourcendatei, dann wird die Standartressourcendatei verwendet – dies wäre in diesem Fall die ApplicationRessources.properties. Hier können zum Beispiel alle englischen Messages gespeichert werden die dann als Standardsprache dienen. Sollen nun beispielsweisedeutsche Benutzer deutsche Texte angezeigt werden ist eine entsprechende Datei mit dem Länderkürzel de anzulegen, also ApplicationResource_de.properties.

Bei diesen Dateien handelt es sich um ganz einfach Textdateien. Abbildung zeigt wie diese Dateien aufgebaut sind.

ApplicationResources.properties (Standart)

startPage.header = Welcome to my website
startPage.text = This is my website and I hope you'll enjoy it!

ApplicationResources_de.properties (Deutsch)
startPage.header = Willkommen auf meiner Webseite
startPage.text = Das ist meine Webseite und ich wünsch euch viel Spass auf ihr!
Einträge in den Ressourcen Dateien

StartPage.header und StartPage.text sind in diesen beiden Dateien die Schlüssel über die das <bean:message/> Tag auf die Nachrichten zugreift. Diese Schlüssel müssen alle Länderressourcen gleich sein! Nur das was hinter dem Gleichheitszeichen steht wird in die jeweilige Landessprache übersetzt. Würde in der deutschen Version der Eintrag StartPage.text=Das ist meine supi dupi geile Webseite Fehlen, würde STRUTS die Message aus der Standartressource laden, in diesem Fall also den Text ,,This is my super duper Website and I hope you’ll enjoy it“ Wird ein Schlüssel angegeben der nicht existiert, kommt es zu einer Fehlermeldung. Benutzt wird das Tag nun wie folgt. Um die Überschrift im Browser auszugeben muss nun ber den Key in der Ressource auf den Text zugegriffen werden.

<bean:message key="startPage.header"/>
Beispielein <bean:message/> Tag

Die Logic Taglib

Im einführenden Beispiel von Kapitel 5 habe ich bereits gezeigt, wie die Logic Taglib das Entwickeln von dynamischen Webanwendungen begünstigt. Das Beispiel zeigt das <logic:iterate/> Tag, welches dazu verwendet wird über Maps und Collections zu iterieren. Einige weitere Tags aus dieser Taglib möchte ich nun erklären.

Das <logic:empty/> und <logic:notEmpty/> Tag

Mit diesen beiden Tags kann überprft werden, ob eine Bean null ist oder im Falle von Collections leer ist. Abhängig davon, ob diese Überprfung true oder false liefert wird der Body des Tags ausgeführt oder nicht. Unser Webseitenbenutzer hat zum Beispiel die Möglichkeit über den Onlineshop Sachen zu kaufen und diese zunächst mal in den Warenkorb zu legen. Jeder Artikel den er in den Warenkorb legt wird in einer Collection mit dem Namen shoppingCart gespeichert. Der Benutzer soll immer die Möglichkeit haben sich den aktuellen Inhalt in seinem Warenkorb anzusehen. Dazu gibt es eine Seite die diesen Warenkorb in einer Tabelle anzeigt. Nun würde es keinen Sinn machen ihm eine Tabelle mit Überschriften zu präsentieren, wenn sein Warenkorb noch leer ist. Also müssen wir vorher prüfen, ob er leer ist oder nicht. Der folgende Code zeigt wie es geht.

<logic:empty name="userBean" property="shoppingCart">
  Sie haben doch noch gar nichts gekauft ?!?
</logic:empty>

<logic:notEmpty name="userBean" property="shoppingCart">
  <table>
    <tr>
      <th>Artikelnummer</th>
      <th>Bezeichnung</th>
      <th>Preis</th>
    </tr>
    // Code der über die Collection mit allen Einträgen iteriert und je eine neue Zeile generiert.
  </table>  
</logic:notEmpty>
Beispielcode<logic:empty/> und <logic:notEmpty>

Das <logic:present/> und <logic:notPresent/> Tag

Ist zum Beispiel aus irgendeinem Grund unsere userBean gar nicht vorhanden (z.B. weil die Session in der sie gespeichert wurde abgelaufen ist), würde es zu einer Fehlermeldung kommen wenn man versucht auf diese Bean zuzugreifen, da diese ja nicht mehr vorhanden ist. Um dies zu vermeiden verwendet man dieses Tag wie folgt.

<logic:present name="userBean">
  // Hier irgendwelche Sachen, die auf die Daten der userBean zugreifen
</logic:present>

<logic:notPresent name="userBean">
  Ihre Session ist abgelaufen. Bitte melden Sie sich erneut an!
</logic:notPresent>
Beispielcode<logic:present/> und <logic:notPresent/>

Das Attribut ,,name“ gibt dabei den Namen der JSP Bean an die auf ihre Existenz zu berprfen ist.

Weitere Tags dieser Taglib

Die Tags <logic:lessThan/> <logic:lessEqual/> <logic:equal/> <logic:notEqual/> <logic:greaterEqual/> und <logic:greaterEqual/> werden dazu verwendet logische Vergleiche zwischen zwei Werten durchzuführen. Je nach Wahrheitsgehalt der Aussage wird deren Body dann ausgeführt oder auch nicht.

Die Tiles Taglib

Neu seit STRUTS 1.1 ist die Tiles Taglib. Ein technisches Detail möchte ich gleich an dieser Stelle erwhnen. Die Verwendung der Tiles Taglib in Tomcat Versionen < 4 möchte ich nicht empfehlen. Beim Versuch eine mit Tiles konfigurierte Anwendung in Tomcat 3.1.28 laufen zu lassen kam es bei mir zu massiven Problemen. Dieses Problem trat reproduzierbar, auf mehreren Installationen und bei unterschiedlichen Benutzern des Frameworks auf. Nachforschungen in diversen Communities und Mailinglisten ergaben, dass die Verwendung von STRUTS 1.1 eine Tomcat Version ab 4 empfohlen
wird.

Zurück zu den Tiles. Von Haus aus gibt es bei JSP leider keine clevere Möglichkeit diese Seiten zu verwalten. Bei Swing Applikationen gibt es dafür LayoutManager, was aber bei JSP? Der <jsp:include> Ansatz hilft lediglich Redundanz zu vermeiden indem wiederkehrender Markup in andere Seiten includet wird. Unübersichtlich bleibt es allemal. Zunächst sollten einige Begriffe geklärt werden, da diese wahrscheinlich nicht allen klar sind. Ein Layout bezeichnet das zumeist einheitlich Aussehen der kompletten Webseite. Es legt das Look & Feel der Seiten fest und wird meist von Designern angefertigt. Das Look & Feel kann größtenteils über CSS festgelegt werden, indem jedem Strukturierungselement ein Stil zugewiesen wird, so können alle Absatztexte beispielsweise in der Farbe blau erscheinen und 11 Pixel Zeichenhöhe haben. Ein Layout legt fest, wie die verschiedenen Elemente einer Webseite zueinander angeordnet sind. Ein Template ist die konkrete Umsetzung des Layouts in Form einer JSP Seite. Eine Komponente ist ein wiederverwertbarer Markup der nicht Teil des Layouts in einem Template ist. Für das Layout sieht es eher schlecht aus. So gibt es keine Möglichkeit zu sagen welcher Inhalt in welchen Rahmen kommt.

Und hier kommen die Tiles ins Spiel. Die Tiles definieren nämlich welche Komponenten welchen Templates zugeordnet werden. Ein Tile repräsentiert einen abgegrenzten Bereich im Layout und kann wiederum andere Tiles enthalten. Eine Webseite besteht aus mindestens einem Tile und alle Tiles zusammengefasst ergeben wieder ein Tile. Die Stellen an denen eine Tile im Template eingefügt werden soll sind durch spezielle Platzhalter markiert. Das beste daran ist die Tatsache, dass zur Laufzeit Parameter einfließen können und so dynamische Layouts entstehen. Definiert und Konfiguriert werden die Tiles in der tiles-defs.xml welche sich im WEB-INF Verzeichnis der Webanwendung befindet. Die einzelnen Tiles Definitionen können voneinander erben und so ganze Hierarchien aufgebaut werden. So könnte eine Definition aussehen:

<tiles-definitions>
  <tiles-definition name=".base" path="/base.jsp">
    <put name="title" value="Mein Seitentitel"/>
    <put name="navigation" value="/navigation.jsp"/>
    <put name="content" value="/welcome.jsp"/>
  </tiles-definition>

  <tiles-definition name=".registration" extends=".base">
    <put name="content" value="/registerUser.jsp"/>
  </tiles-definition>
</tiles-definitions>
Definition von tiles in der tiles-defs.xml

Folgende Abbildung stellt das bisherige nochmal grafisch dar.

Funktionsweise von tiles

Funktionsweise von tiles

Ausgangspunkt und Startseiteeine Anwendung könnte beispielsweise eine JSP Seite mit dem Namen base.jsp sein. Diese Datei ist ein Template und enthält bereits alle immer wiederkehrenden Layoutelemente wie Firmenlogo, Banner, etc. Die Platzhalter befinden sich an den Stellen, an denen dynamisch die Inhalte eingefügt werden sollen. Das sieht dann so aus:

<table with="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td><tiles:insert attribute="title"/></td>
  </tr>
  <tr>
    <td><tiles:insert attribute="navigation"/></td>
    <td><tiles:insert attribute="content"/></td>
  </tr>
</table>
Beispiel zur Verwendung von tiles

Beim Aufruf der Seite mit der Benutzerregistrierung wird das Tile .registration verwendet. Es erbt von .base und überschreibt das Attribut content mit einer anderen JSP Seite. Außer dem Inhalt im mittleren Teil bleibt also alles gleich. Anstelle bei den Forwards in der struts-config.xml nun direkt JSP Seiten anzugeben wird ein Tile angegeben zu dem gesprungen wird. Auf diese Weise lässt sich ein komplettes Webprojekt sehr einfach und schnell aufbauen und was noch viel wichtiger ist in der kurzlebigen Zeit von Websites auch sehr schnell komplett umstrukturieren, da ja nur noch eine XML Datei angepasst werden muss.

STRUTS Konfiguration

Die Konfiguration von STRUTS erfolgt mit einer Ausnahme in einer einzigen Datei, nämlich in der struts-config.xml. Diese liegt bei Tomcat im WEB-INF Verzeichnis der jeweiligen Webanwendung. Einzig in der web.xml welche im selben Verzeichnis liegt muss ein ActionMapping eingetragen werden, damit Tomcat ,,weis“, wann es einen Request an das ActionServlet von STRUTS weiterzuleiten hat. Die Abbildung zeigt wie diese Konfiguration in der web.xml auszusehen hat.

[...]
<web-app Hier noch einige Attribute in Abhängigkeit der Version>
  <!-- Standard Action Servlet Configuration (with debugging) -->
  <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>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
 </servlet>

  <!-- Standard Action Servlet Mapping -->
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>
Konfiguration in web.xml

Alle Requests mit der Endung .do werden nun an das STRUTS ActionServlet weitergeleitet. Statt .do können auch beliebige andere Suffixe eingetragen werden ( .ba, .java, .hasteNichtGesehen, usw.) Der Rest der STRUTS Konfiguration erfolgt nun nur noch in der struts-config.xml und falls Tiles verwendet werden auch noch in der tiles-defs.xml. Beide Files befinden sich im WEB-INF Verzeichnis der jeweiligen Webanwendung. In dieses Verzeichnis gehören außerdem alle TLD’s. In das Verzeichnis WEB-INF/lib muss noch die struts.jar, kopiert werden. In diesem Verzeichnis befinden sich auch alle anderen JAR Files die die Webanwendung benötigt werden. Dazu gehören z.B. Die Bibliothekenden Zugriff auf Datenbanken.

Forms

Alle ActionForm Klassen müssen dem STRUTS Framwork noch bekannt gemacht werden, damit die Actions darauf zugreifen können. Die Abbildung zeigt wie dieser Eintrag in der struts-config.xml unser Beispiel mit der LoginForm auszusehen hätte.

<form-beans>
  <form-bean name="LoginForm" type="myPackage.forms.LoginForm">
</form-beans>
Konfiguration von ActionForms

Über das Attribut „name“ wird diese ActionForm bekannt gemacht. Das Attribut „type“ gibt die Klasse an die sich hinter dieser ActionForm verbirgt.

Forwards

Über globale Forwards bleibt das MVC-Prinzip gewahrt, da es ja vermieden werden soll von einer JSP Seite zur anderen zu verlinken. Die Kontrolle soll wie der Name schon sagt im Controller bleiben und das wird unter anderem über Globale Forwards realisiert.

<global-forwards>
  <forward name="login_page" path=".login"/>
</global-forwards>
Konfiguration von Forwards

Listing 6.3 zeigt einen Eintragein globales Forward in der struts-config.xml. Über das Attribut „name“ können Actions auf dieses Forward Element zugreifen. Das Attribut „path“ gibt entweder eine JSP Datei, oder wie in diesem Beispiel ein Tile an. Für die Namen gibt es keine Beschränkungen, jedoch sollte man sich eine Nomenklatur überlegen um in großen Projekten nicht die Übersicht zu verlieren.

Actions

Alle Actionklassen müssen dem Framework in der struts-config.xml mitgeteilt werden. Diese ActionMappings stehen dabei zwischen den Tags <action-mappings> und </action-mappings>. Der Eintrag in Abbildung ist das Beispiel mit dem Login.

<action-mappings>
  <action path="/login" type="myPackage.actions.LoginAction" unknown="true" parameter="param"/>
</action-mappings>
Konfiguration von Actions

Überdas Attribut „path“ ist diese Actiondas Framework ansprechbar. Dieser Name wird zum Beispiel bei <html:link/> verwendet.

<html:link action="login">Login</html:link>
Verwendung der Action in <html:link/>

Das Attribut „type“ gibt die Actionklasse an. Die Attribute ünknown“ und „parameter“ sind optional. Wird unknown auf true gesetzt, ist diese Action die Standartaction. Dies kann notwendig werden wenn die Session lange inaktiv war und der Benutzer erneut einen Link klickt. STRUTS kann dann nicht mehr zu der gewünschten Action springen und verwendet stattdessen das Mapping dessen Attribut ünknown“ auf true gesetzt ist. Den Actions kann auch ein Parameter mitgegeben werden. Diesen Parameter kann man in der Actionklasse in der execute() Methode auslesen wie folgendes Listing zeigt:

mapping.getParameter();
Auslesen von Parametern einer Action Definition

„mapping“ ist dabei der Übergabeparameter ActionMapping der execute() Methode. Will man mehrere Parameter bergeben, so müssen diese mit einem Trennzeichen voneinander getrennt werden. Dies kann zum Beispiel ein Semikolon sein. In der Actionklasse wird dann dieser Parameterstring mit einem StringTokenizer wieder in einzelne Parameter „zerlegt“. Auch bei den ActionMappings gilt: Eine gute Nomenklatur bei der Namensgebung hilft in großen Projekten die Übersicht zu behalten!

Attribute der STRUTS Tags

In diesem Kapitel möchte ich einige Tags aus der STRUTS Taglib die wichtigsten Attribute auflisten und beschreiben. Die Tabellen erheben keinen Anspruch auf Vollständigkeit. Einige Attribute habe ich weggelassen, weil sie mir weniger wichtig erschienen. Exemplarisch habe ich beim <html:form/> Tag die Attribute ßtyle“ und ßtyleClass“ beschrieben. Diese Attribute dienen der Formatierung und existieren auch die meisten der anderen Tags aus der HTML Taglib.

HTML Taglib

Attribute<html:link/>

AttributBeschreibung
forwardBenutzt eine globale ActionForward Definition aus der struts-config.xml zur Erzeugung der URL
pageGeneriert die URL relativ zum Kontext der Applikation
hrefDamit kann eine statische URL angegeben werden die möglicherweise auߟerhalb des Gültigkeitsbereiches der eigenen Anwendung liegt.
nameName einer Bean welche Parameterdie URL enthält
propertyName des Properties in der Bean, welches die Parameter Keys und Values in Form einer java.util.Map enthält.
paramIdName des Parameters in der URL
paramNameName der Bean welche das Propertyden Wert enthält
paramPropertyProperty in der Bean, welches den Wertden URL Parameter enthält.
transactionWird transaction mit "true" angegeben wird an die URL ein Token Parameter angehangen. Dies ist dann sinnvoll, wenn verhindert werden soll, dass mehrfaches Anklicken eines Links zu unerwünschten Ergebnissen führt. Das Token kann dann in der ActionKlasse ausgewertet werden. Bei mehrfachem Anklicken eines Links kann hier geprüft werden, ob die nachfolgende Routine ausgeführt werden soll oder nicht.

Attribute<html:form/>

AttributBeschreibung
actionDas Valuedieses Attribut enthlt den Pfad zu einer in der struts-config.xml konfigurierten Action
focusDer Name des Feldes innerhalb von , welches beim Laden der Seite vorselektiert sein soll. Die Implementierung erfolgt über JavaScript.
styleCascading Style Sheet, mit dem das form Tag formatiert werden soll.
styleClassName der Style Sheet Klasse, die die Formatierungsanweisungen das form Tag enthält.
targetZielfenster für die Ausgabe (Z.B. wenn Frames verwendet werden)
enctypePer Default ist der Wert dieses Attributes auf Application/x-www-form-urlencoded" gesetzt. Sollen mit dem Formular Dateien vom Client zum Server übertragen werden, so muss der Wert auf "multipart/form-data" gesetzt werden.

Attribute<html:errors/>

Falls in einer Action Klasse Fehler aufgetreten sind können diese in einem ActionErrors Objekt gespeichert werden. Das <html:errors/> Objekt gibt diese Fehler dann aus. Natürlich können diese Fehlermeldungen auch internationalisiert werden. Dazu müssen in den Ressourcen folgende Einträge vorgenommen werden:

SchlüsselBeschreibung
errors.prefixDieser Text wird der Fehlermeldung vorangestellt.
errors.postfixDieser Text wird an die Fehlermeldung hinten angehangen.
errors.headerKopf für die Fehlermeldung. Z.B. <tr>
errors.footerEnde der Fehlermeldung. Z.B. </tr>
AttributBeschreibung
nameFehlermeldungen können auch in der Actionklasse in einer Bean gespeichert werden. In diesem Fall gibt "name" den Namen der Bean an, welche die Schlüssel (Keys) die Fehlermeldungen enthält.
propertyDer Wert dieses Attributes bezeichnet den Namen eines Formularelementes. Falls dieses optionale Attribut gesetzt wird, werden Fehlermeldungen das spezifizierte Element ausgegeben.

BEAN Taglib

Attribute<bean:define/>

Um innerhalb einer JSP Seite auf die Daten einer Bean zugreifen zu können, muss diese der JSP Seite zunchst bekannt gemacht werden. Über das Attribut ïd“ können andere Tags wie bean:write auf die Bean zugreifen.

AttributBeschreibung
nameFehlermeldungen können auch in der Actionklasse in einer Bean gespeichert werden. In diesem Fall gibt "name" den Namen der Bean an, welche die Schlüssel (Keys) die Fehlermeldungen enthält.
propertyDer Wert dieses Attributes bezeichnet den Namen eines Formularelementes. Falls dieses optionale Attribut gesetzt wird, werden Fehlermeldungen das spezifizierte Element ausgegeben.

Attribute<bean:write/>

AttributBeschreibung
nameName der Bean die den auszugebenden Wert enthält
propertyDas Property der Bean welches ausgegeben werden soll. Handelt es sich bei der Bean um einen einfachen Datentypen wie String, dann entfällt das Attribut "property" und es reicht der Name der Bean
filterEnthält der auszugebende Text HTML Steuerzeichen (z.B.

) und es ist nicht die Umsetzung der Logik dieser Zeichen gewünscht, sondern deren Anzeige, so wie sie im Text steht, wird filter auf true gesetzt

LOGIC Taglib

Attribute<logic:empty/> & <logic:notEmpty/>

AttributBeschreibung
nameName der Bean, welche getestet werden soll
propertyProperty der Bean das getestet werden soll
scopeScope in dem die Bean gesucht werden soll. Wird sŸcope nicht angegeben, werden alle Scopes durchsucht.

Attribute<logic:present/> & <logic:notPresent/>

AttributBeschreibung
nameTestet ob eine Bean mit diesem Namen existiert oder nicht
propertyTestet ob das Property in der Bean existiert oder nicht
scopeScope in dem die Bean gesucht werden soll. Wird "SŸcope" nicht angegeben, werden alle Scopes durchsucht.