JSF Ext
This is version . It is not the current version, and thus it cannot be edited.
Back to current version   Restore this version

JSF Ext (vorher JSF Desktop) ist eine Erweiterung von JSF 2 (2.0, 2.1) um einige grundlegende Features, die man für saubere, funktionale AJAX-Applikationen braucht.

Einige der Features:

Inhalt#

Overview#

The main features of the JSF-Ext (formerly JSF Desktop) are:

Kompatibilität#

Demo unserer Desktop-Plattform auf der Basis von JSF v2, die auch auf GAE lauffähig ist:

Damit setzen Sie komplexe, interaktive Applications im Handumdrehen auf.

Configuration#

In the pom.xml use:
    <dependency>
        <groupId>com.intersult</groupId>
        <artifactId>jsf-ext</artifactId>
        <version>1.1-SNAPSHOT</version>
    </dependency>

    <repository>
        <id>intersult-repository</id>
        <name>Intersult Repository</name>
        <url>http://repository.intersult.com/repository</url>
    </repository>

In the web.xml use:

<context-param>
    <param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
    <param-value>com.intersult.jsf_ext.util.ClassPathResourceResolver</param-value>
</context-param>

Access via http://localhost/faces/resource/<test.xhtml>

Insert-Tag#

The Insert-Tag can insert UIComponent objects into the component tree. This is usefull when creating XHTML-Components with namespace http://java.sun.com/jsf/composite/...

Example#

Imagin a component which evenly distributes Command-Buttons in a form. You'de like to create a component (luckily this is already included in JSF Ext). The component should wrap each contained component in a SPAN-Tag with some padding.

Solution: You iterate through the children and write a span for each child. Into the span you insert the child itself. With normal JSF-Tags this is not possible, you need <i:insert>

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:cc="http://java.sun.com/jsf/composite"
	xmlns:e="http://intersult.com/jsf/ext"
	xmlns:ext="http://java.sun.com/jsf/composite/ext"
>
	<cc:interface>
		<cc:attribute name="align"/>
	</cc:interface>
	<cc:implementation>
		<div style="margin-top: 10px; text-align: #{empty cc.attrs.align ? 'center' : cc.attrs.align};">
			<ui:repeat value="#{cc.children}" var="child">
				<span style="margin-right: 5px;">
					<i:insert component="#{child}"/>
				</span>
			</ui:repeat>
		</div>
	</cc:implementation>
</html>

Events#

Events sind eine Erweiterung des Action- und Update-Systems von JSF. Events können von der Java- und XHTML-Seite erzeugt und konsumiert werden.

NameJavaParameterBeschreibung
com.intersult.post_constructEvent.EVENT_POST_CONSTRUCTObject managedBeanDer Event wird nach dem Erzeugen einer managed Bean durch das JSF-System erzeugt.
com.intersult.pre_destroyEvent.EVENT_PRE_DESTROYDer Event wird vor dem Entfernen einer managed Bean erzeugt.
com.intersult.eventEvent.EVENT_EVENTString event, Object... argumentsDieser Meta-Event wird bei jedem Event erzeugt, sodass allgemeine Event-Handler geschrieben werden können. Dies ist mit Vorsicht zu verwenden.
com.intersult.messagesMessageHandler.EVENT-Der Event wird erzeugt, wenn Faces Messages vorliegen.
login.beforeLogin.EVENT_LOGIN_BEFORE-Bevor ein Benutzer eingeloggt wird.
login.successLogin.EVENT_LOGIN_SUCCESS-Nachdem ein Benutzer erfolgreich eingeloggt wurde. Der Benutzer ist über Login.instance().getUser() abrufbar.
login.failLogin.EVENT_LOGIN_FAIL-Nachdem ein Login fehlgeschlagen ist.
login.afterLogin.EVENT_LOGIN_AFTER-Nach dem Login-Prozess, unabhängig ob er erfolgreich oder fehlgeschlagen ist.
login.logoutLogin.EVENT_LOGOUT-Nach dem Logout.

Java#

Ein Event wird erzeugt, indem die Instanz von Event geholt wird. Dies kann durch @ManagedProperty("#{event}") geschehen oder durch die statische Methode Event.instance(). Dabei ist zu beachten, dass keine Session scoped Bean in einen Application Context injected wird.

Das Session basierte Event-Objekt enthält die Methode raise(String event, Object... arguments), also im einfachsten Fall:

	Event.instance().raise("com.intersult.some-event");

Die Events werden in der Regel durch eine Annotation konsumiert:

	@Listener("com.intersult.some-event")
	public void someEvent() {
	}

Es ist zu beachten, dass Events nur empfangen werden wenn eine Bean tatsächlich instantiiert ist.

XHTML#

Events können auch in XHTML verarbeitet werden. Zum Beispiel der vorgefertigte Event com.intersult.messages, der bei vorhandenen Faces-Messages ausgelöst wird:
<h:messages id="messages" globalOnly="true">
    <e:update event="com.intersult.messages"/>
</h:message>

Ergebnis: Die Faces-Messages werden gerendered, ohne dass bei jedem AJAX-Tag ein gesondertes Rendered-Attribut angegeben werden muss.

Raise-Component#

Events können hervorragend dazu benutzt werden, um AJAX-Submits und Rerendering voneinander zu trennen. Events werden dabei durch Components erzeugt und von anderen Components konsumiert. So braucht die erzeugende Component zur Erstellungszeit nicht wissen, welche Components rerendered werden:
<h:commandButton value="Submit">
	<f:ajax execute="@form"/>
	<e:raise name="com.intersult.test"/>
</h:commandButton>

Hier ist zu beachten, dass ein AJAX-Tag zusätzlich verwendet wird. Bei vollen GET- oder POST-Requests machen Events keinen Sinn, da hier sowieso die komplette Seite gerendered werden würde.

Das Konsumieren kann wieder auf ähnliche Weise erfolgen:

<h:outputText id="output" value="#{bean.text}">
	<e:update event="com.intersult.test"/>
</h:outputText>

Es ist zu beachten, dass bei der Update-Component (hier outputText) eine Id angegeben wird, damit der AJAX-Handler das Rerendering zuordnen kann. Dies tritt beim Verwenden des render-Attributs nicht auf, da durch die Angabe einer Id ja eine vergeben wurde.

Hinweise#

Events sind momentan Session-basiert, das heißt es existieren keine Application übergreifenden Events.

Konfiguration#

JSF Ext ist darauf ausgelegt, ohne größere Konfiguration benutzt werden zu können. Viele Features können Out-of-the-Box verwendet werden, sobald sich das jsf-ext.jar in der Web-Application befindet.

Bei einigen Features und Konstellationen ist es von Vorteil, bestimmte Konfigurationen vorzunehmen.

Annotations und InjectionProvider#

Wie bereits in JSF2 erwähnt, werden in einigen Servlet-Containern die Annotations nicht verarbeitet. JSF Ext registriert einen sogenannten InjectionProvider, was im Normalfall transparent funktioniert.

Falls man feststellt, dass die Events im JSF Ext nicht arbeiten, Oberflächenelemente nicht aktualisiert werden und Messages nicht angezeigt werden, dann arbeiten vermutlich auch übliche JSF-Annotations @ManagedBean oder @SessionScoped nicht. Abhilfe schafft dann:

	<context-param>
		<param-name>com.sun.faces.injectionProvider</param-name>
		<param-value>com.intersult.jsf_ext.event.EventInjectionProvider</param-value>
	</context-param>