Das Behavior API - JAXenter
FacesTales

Das Behavior API

Lars Röwekamp und Matthias Weßendorf

Das neue Behavior API von JSF 2.0 stellt die Basis für den deklarativen Ajax-Support mittels dar. Darüber hinaus bietet das API einen komfortablen Ansatz, um (eigenes) JavaScript mit den JSF-2.0-Komponenten zu verbinden.

Keine Ajax-Komponenten

Damit JSF 2.0 Ajax versteht, braucht es ein eigenes JavaScript API. Dies soll von Herstellern genutzt werden, wenn die eigenen Komponenten – via Ajax – mit dem „Faces Lifecycle“ kommunizieren. Allerdings sollte ein Endbenutzer damit in erster Linie keinen Kontakt haben. Statt nun neue und sinnfreie Komponenten, wie beispielsweise <h:ajaxCommandButton/> , einzuführen, wurde das Behavior API entworfen. Die Idee dazu ist nicht ganz neu: Für Konvertierungs- und Validierungsregeln wurde bereits in JSF 1.0 auf attached objects zurückgegriffen. Damit eine Komponente ein Behavior enthalten kann, muss die Komponente das ClientBehaviorHolder-Interface implementieren. Hier wurde ebenfalls das bewährte Muster der Converter und Validator übernommen, die nur innerhalb eines (Editable)ValueHoders nutzbar sind. Das Injecten von JavaScript mit einem Behavior ist ebenfalls nichts Neues: Das ADF Faces Project bietet ähnliches Verhalten für seine umfangreiche JavaScript-Bibliothek an. Mit ADF Faces kann ein Entwickler JavaScript-Funktionalität mittels einfacher Behavior-Tags in die Faces-View einfügen:


...

...
Hello World Behavior

Wie auch für die Entwicklung von UI-Komponenten (mit der Klasse UIComponentBase) gibt es für eigene Behavior-Implementierungen eine so genannte Convenience Implementation, die Klasse ClientBehaviorBase. Innerhalb der überschriebenen getScript()-Methode wird der konkrete JavaScript-Aufruf zurückgegeben. Fertig ist die erste Behavior-Klasse:

@FacesBehavior("com.entwickler.faces.tales.behavior.Confirm")
public class ConfirmBehavior extends ClientBehaviorBase
{
   @Override
   public String getScript(ClientBehaviorContext behaviorContext)
   {
      return "return confirm('" + getConfirmText() + "')";
   }
  // GET AND SET NEEDED!
   private String confirmText = "Are you sure?";
}

Die @FacesBehavior-Annotation stellt sicher, dass das Behavior bei der verwendeten JSF-Laufzeitumgebung registriert wird. Alternativ könnte ein Eintrag innerhalb der faces-config.xml erfolgen, die allerdings dank des in JSF 2.0 strikt verfolgten Convention-over-Code-Ansatzes fast nicht mehr notwendig ist. Ein Behavior wird als Bestandteil einer Tag Library zur Verfügung gestellt und kann so via eigenem TAG in eine XHTML-Seite (Nein, JSP funktioniert hier nicht mehr!) eingebunden werden. Was sich schmerzhaft anhört, tut gar nicht weh: Für einfache Behavior-Implementierungen reicht glücklicherweise eine kleine facelet-taglib-XML-Datei:

http://entwickler.com/facesTalesconfirmcom.entwickler.faces.tales.behavior.Confirm

Innerhalb der XML-Datei wird das eigene Behavior dem confirm-Tag zugeordnet, sodass es direkt innerhalb einer XHTML-Datei nutzbar ist:

Wird das confirmText-Attribut nicht angegeben, so kommt der im Beispiel nicht internationalisierte Standardtext zum Zug.

Ist das alles?

Das Confirm-Behavior ist sicherlich nützlich für manch ein JSF-Projekt, allerdings ist damit noch längst nicht das Ende der Fahnenstange erreicht. Moderne JavaScript-Frameworks, wie z. B. JQuery, bieten zahlreiche Effekte und/oder Widgets an, die mit einem Behavior in die eigenen JSF-Anwendungen eingebaut werden können. Ein mögliches Beispiel wäre das Anzeigen eines besonderen (Context-)Menüs, wenn der Benutzer mit der Maus über ein bestimmtes JSF-Control fährt (mouseover). Achtung: Die <h:outputText /> -Komponente implementiert das ClientBehaviorHolder -Interface nicht! Der Grund hierfür ist, dass diese Komponente bewusst sehr klein gehalten wurde. Sie besitzt ebenfalls keine onXzy-Attribute, z. B. die <h:outputLabel /> -Komponente. Als Alternative zur Verwendung eines <outputLabel> bietet sich ein <h:panelGrid/> an, das als Container für das <h:outputText/> -Tag und ein zusätzliches Behavior genutzt werden kann:

panelGrid>

Fazit und Ausblick

Das neue Behavior-API bietet eine solide Möglichkeit, funktionales JavaScript in die Anwendung zu integrieren. Das Behavior-API ermöglicht so einen hohen Grad der Wiederverwendung bei der JavaScript-Integration. In der nächsten Ausgabe der Faces-Tales-Kolumne wird ein komplexeres Behavior erstellt, bei dem verschiedene Bestandteile, z. B. JavaScript-Dateien, eine ClientBehaviorRenderer-Klasse oder ein (Facelets) BehaviorHandler für ein Real-World Behavior sorgen.

Lars Röwekamp ist Geschäftführer der OpenKnowledge GmbH und berät seit mehr als 10 Jahren Kunden in internationalen Projekten rund um das Thema Enterprise Computing (Twitter: @mobileLarson).

Matthias Weßendorf arbeitet für die Oracle an einer Server-Side-Push Lösung für ADF Faces. Er ist PMC Chair von Apache MyFaces. Matthias bloggt regelmäßig auf http://matthiaswessendorf.wordpress.com (Twitter: @mwessendorf).

Geschrieben von
Lars Röwekamp und Matthias Weßendorf
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.