Mit ‘Struts 2’ getaggte Artikel

Struts 2 Tags

Mittwoch, 25. Februar 2009

Struts2 bringt eine Vielzahl an vorgefertigten Tags mit, die einen Großteil der Anforderungen an eine Webanwendung abdecken. Im Folgenden soll etwas auf einige dieser Tags eingegangen werden.
Generell unterscheidet man bei Struts2 zwischen „generischen Tags“ und „Benutzerinterface Tags“ (UI Tags). Die generischen Tags sind z.B. für Datenverarbeitung und Kontrollfluss zuständig (z. B. Property- oder  if- Tag) während die UI-Tags in aller Regel dem Benutzer Eingabemöglichkeit zur Verfügung stellen. Ein wichtiger Unterschied ist hier auch, dass UI-Tags mittels Themes und Templates modifiziert werde können.

Die Attribute der Tags werden teilweise automatisch als OGNL-Ausdruck ausgewertet, teilweise als  String. Möchte man die Auswertung als Ausdruck erzwingen kann man den Wert in %{myValue} einschließen. Benutzt man %{} für Attribute, die sowieso einen OGNL Ausdruck erwarten und auswerten, so wird die Escape-Sequenz automatisch ignoriert. D.h. ist man sich nicht sicher, ob ein Attribut evaluiert wird, man möchte aber z.B. auf Action-Properties zugreifen, kann man ohne Probleme das Attribut in %{} einschließen.
Als Beispiel das  if-Tag:

<s:if test="%{showItem1}">
	<s:property name="%{item1}">
</s:if><s:elseif test="showItem2">
	<s:property name="item2">
</s:elseif>

Beide test-Attribute werden als OGNL-Ausdruck ausgewertet, bei dem ersten wird das %{} ignoriert.

Möchte man in einem Attribut, das Ausgewertet wird, allerdings nicht auf ein Objekt auf dem Stack  setzen, sondern auf einen String, muss man ihn explizit mit Anführungszeichen als String deklarieren.
Dies kann z.B. bei der Benutzung des URL-Tags sinnvoll sein:
Möchte man einen Link auf eine andere Action erstellen, bietet sich hierfür die Benutzung des URL-Tags an. Möchte man z.B. auf eine Action in dem selben Namespace verweisen, so ist es nicht nötig diesen Anzugeben und es reicht, den Namen einer Action zu benennen. Außerdem sorgt der URL-Tag automatisch dafür, dass – sofern gewünscht -  auf ältere Parameter mit übergeben werden.

<s:url action="nextAction" includeParams="get">
	<s:param name="param1" value="object1"/>
	<s:param name="param2" value="%{'hello'}"/>
	<s:param name="param3">world</s:param>
</s:url>

Im obigen Beispiel wird param1 als Objekt interpretiert und getObject1() aufgerufen, die beiden anderen Parameter werden mit Strings belegt.

Möchte man HTML-Tags und Struts2-Tags miteinander verschachteln, so muss man die richtige Verwendung der einfachen und doppelten Anführungszeichen beachten, um nicht aus Versehen das Attribut des übergeordneten Tags zu früh zu schließen:
Falsch:

<a href="<s:url action="nextAction" includeParams="get"/>">next</a>

Richtig:

<a href="<s:url action='nextAction' includeParams='get'/>">next</a>

Spätestens bei URLs mit Parametern wie oben, verbietet es sich aus Gründen der Lesbarkeit, den URL-Tag in dem A-Tag direkt zu schreiben. Um dies zu vermeiden, gibt es zum Beispiel die Möglichkeit die URL mittels das id-Attributs (ab Struts 2.1 var-Attribut) an einen Alias zu binden. Diese kann dann mittels Property-Tag aufgerufen werden.

<s:url id= "nextURL"  action="nextAction" includeParams="get">
	<s:param name="param1" value="object1"/>
	<s:param name="param2" value="%{'hello'}"/>
	<s:param name="param3">world</s:param>
</s:url>
<a href="<s:property name='nextURL'/>">next</a>

Zu beachten bei der Verwendung der einfachen Anführungszeichen ist, dass einzelne Zeichen in einfachen Anführungszeichen als Character gelten und nicht als String. Beispiel:

private letter = "A";
 
public String getLetter(){
    return letter;
}
<s:if test="letter.equals('A')">
	A wie Anton
</s:if>

Dies funktioniert nicht. Möglich wären:

<s:if test='letter.equals("A")'>
	A wie Anton
</s:if>

oder

<s:if test="letter.equals(\"A\")">
	A wie Anton
</s:if>

Sven Grünewald


Themes, Tags und Templates in Struts2

Montag, 13. Oktober 2008

In Struts2 ist die Art und Weise, mit der UI-Tags gerendert werden, in so genannten Themes zusammengefaßt. Diese Themes bestehen aus einzelnen FreeMarker-Templates, wobei für jeden Tag mehr oder weniger ein Template existiert.

In Struts2 sind mehre Themes schon von Hause aus enthalten:

  • simple
  • xhtml
  • css_xhtml
  • ajax

Das “simple”-Theme stellt dabei nur die Basisfunktionalität von Struts2 zu Verfügung und überläßt das Design vollständig dem Entwickler. Alle anderen Themes stellen u.A. clientseitige, JS-basierte Validierung zur Verfügung, greifen allerdings auch in Designentscheidungen ein. Wobei das “css-xhtml”-Theme ein zweispaltiges Layout wählt und alle Elemente in <div>-Tags kapselt, so dass diese mit CSS formatiert werden können. Das “xhtml”-Theme und das darauf aufbauende “ajax”-Theme bestimmen von sich aus viele Teile des Designes. So statten sie input-Felder gleich mit einer Beschreibung aus und platzieren Feldfehler direkt an das auslösende Feld. Da man aber meist ein anderes Design wünscht, als die Struts2-Entwickler sich denken, kann man eigene Themes erstellen oder bestehende Themes anpassen.

Als Grundlage bietet sich das “simple”-Theme an, da es den Entwickler am wenigsten “bevormundet”. Um nicht das Rad komplett neu zu erfinden, kann man das “simple”-Theme an das eigene Theme vererben. Dies geschieht durch den Eintrag parent=simple in der “theme.properties”-Datei im Verzeichnis des neuen Themes, also z.B. “/template/buj_theme/theme.properties”. Ist nun das “buj_theme” ausgewählt, werden die Templates in diesem Ordner benutzt, falls vorhanden, sonst das “simple”-Theme.

Welches Theme benutzt wird, kann von Tag zu Tag entschieden werden (Tag-Attribut theme=“…”) und es kann ein globales Default-Theme gewählt werden, beispielsweise durch struts.ui.theme=buj_theme in der “struts.properties”.

Möchte man eigene Tags erstellen, so braucht man nur eine neue FreeMarkerDatei (.ftl-Endung) in dem Template-Verzeichnis erstellen, auf die man dann mit

<s:component template="meinTag"/>

zurückgreifen kann. Mit

<s:component template="meinTag">
    <s:param name="param1" value="value1"/>
</s:component>

kann man Parameter an die Tagauswertung übergeben, die dann in dem Template unter Anderem mit ${parameters.param1} ausgelesen werden können.

In den Freemarker-Templates kann man auch die aus Struts2 bekannte Sprache OGNL benutzen, allerdings mit $ anstatt %. Beachte: ${parameters.x} greift hierbei auf die Paramter/Attribute das Tags zu während ${Parameters.x} den Requestparameter x ausliest.

Probleme: Modifiziert man bestehende Templates, so kann es vorkommen, dass Tag-Attribute die Action-Properties überschatten. Gibt es in der Action ein Feld “id” so kann nicht (OGNL typisch) mit ${id} darauf zugegriffen werden, wenn das Tag auch ein Attribut “id” besitzt, selbst wenn dieses nicht gesetzt ist.

Auf das Action-”id” kann statt dessen mit ${action.id} zugegriffen werden.

Möchte man in dem Template Struts2-Tags benutzen, kann man dies mit <@s.iterator… statt mit <s:iterator… tun.

Leider ist das Thema “Schreiben eigener Tags” in FreeMarker/Struts2 kaum dokumentiert, vor allem was die Struts2 spezifischen Details angeht, und deshalb heißt es im Moment leider noch „Probieren geht über Studieren“.


Alexander Draeger