Hier sind einige Informationen über JSF 2 gespeichert.
Google Richfaces vs Primefaces Trends#
Composite Tags#
- Auch bezeichnet als On-The-Fly-Tags, Facelet-2.0-Tags
- Include xmlns:x="http://java.sun.com/jsf/composite/path" heißt dass alle Tags unter /resources/path/... geladen werden.
- Tags fügen immer eine Komponente im Komponentenbaum ein.
- Tags sind UI-Naming-Container, daher entstehen keine Konflikte beim mehrfachen Einfügen der 2.0-Tags. Allerdings ist das auch beim Zugriffspfad zu beachten.
- Definition des Interface durch die View
- Erweiterung des Interface durch
- ActionSource Es können endlich Actions über EL-Expressions gebunden werden. Dies war bisher das größte Problem bei der Herstellung vollwertiger Komponenten durch Facelets.
- ValueHolder
- EditableValueHolder
- RenderFacet 2.0-Tags können vollwertige Facets enthalten genau wie echte Komponenten. Dadurch ist die Verwendung hässlicher UI-Inserts nicht mehr nötig.
- InsertFacet Facets können auch in Subkomponenten applied werden.
- Zugriff aus die Komponente durch EL-Expressions durch #{cc} oder
- Die Attribute werden nicht mehr unkontrolliert nach innen propagiert, was früher teils zu üblen Fehlern geführt hat. Der Zugriff erfolgt nun über #{cc.attrs} also zum Beispiel #{cc.attrs.value} für den Parameter
- Zugriff auf die id über #{cc.id} und sogar auf die Client-Id #{cc.clientId}
AJAX Status#
Die Component zeit den AJAX-Status an.<?xml version="1.0" encoding="UTF-8"?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:cc="http://java.sun.com/jsf/composite" > <cc:interface> <cc:attribute name="status" default="begin"/> </cc:interface> <cc:implementation> <script type="text/javascript"> jsf.ajax.addOnEvent(function(data) { document.getElementById('#{cc.clientId}:status').style.visibility = data.status == '#{cc.attrs.status}' ? 'visible' : 'hidden'; }); </script> <div id="#{cc.clientId}:status" style="visibility: hidden;"> <cc:insertChildren/> </div> </cc:implementation> </html>
Verwendung zum Beispiel wie folgt:
<test:ajaxStatus> <h:graphicImage value="/images/wait30trans.gif"/> </test:ajaxStatus>
HTML Element Tag#
Der Tag rendert ein HTML-Element mit ClientId und übergibt alle Attribute und Childrens.<?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:c="http://java.sun.com/jsp/jstl/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:cc="http://java.sun.com/jsf/composite" > <cc:interface name="test"> <cc:attribute name="element" required="true"/> <cc:attribute name="rendered"/> </cc:interface> <cc:implementation> <c:if test="#{!rendered or rendered}"> <h:outputText value="<#{cc.attrs.element} id="#{cc.clientId}"" escape="false"/> <c:forEach items="#{cc.attributes}" var="attribute"> <h:outputText value=" #{attribute.key}="#{attribute.value}"" escape="false" rendered="#{!attribute.key.startsWith('javax.faces') and !attribute.key.startsWith('com.sun') and attribute.key != 'element' and attribute.key != 'rendered'}"/> </c:forEach> <h:outputText value=">" escape="false"/> <cc:insertChildren/> <h:outputText value="</#{cc.attrs.element}>" escape="false"/> </c:if> </cc:implementation> </html>
Validierung prüfen#
FacesContext.getCurrentInstance().isValidationFailed(); #{facesContext.validationFailed}
Setup#
web.xml<context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>server</param-value> </context-param> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <context-param> <param-name>javax.faces.FACELETS_LIBRARIES</param-name> <param-value>/WEB-INF/test.taglib.xml</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping>
EL-Expressions 2.1#
Die neuen EL-Expressions erlauben das Binding an Action-Methods, die Parameter besitzen:<h:commandButton value="Test" action="#{test.action('param')}"/>
In der pom.xml die Libs referenzieren:
<dependency> <groupId>javax.el</groupId> <artifactId>el-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>el-impl</artifactId> <version>2.2</version> </dependency> <repository> <id>maven.java.net</id> <name>Java.net Maven2 Repository</name> <url>http://download.java.net/maven/2</url> </repository>
Und in der web.xml die Factory festlegen:
<context-param> <param-name>com.sun.faces.expressionFactory</param-name> <param-value>com.sun.el.ExpressionFactoryImpl</param-value> </context-param>
In Google Application Engine klappt das nicht, dort kann nur JBoss EL verwendet werden.
Debugging#
Debug Page#
Die Debug-Page von Facelets öffnet sich bei einer Exception. Sie kann aber auch manuell geöffnet werden, dies ist nützlich um die Bean-Scopes zu untersuchen oder den Component-Tree. Dazu einfach das Tag einfügen:<ui:debug hotkey="q"/>
Das Hotkey arbeitet in diesem Fall mit CTRL+SHIFT+Q. Falls das Hotkey nicht funktioniert, ist es wahrscheinlich durch etwas anderes abgefangen und man ersetzt es durch ein anderes.
Gelbe Messages#
Werden gelbe Warnings wie z.B. "The form component needs to have a UIForm in its ancestry. Suggestion: enclose the necessary components within <h:form>" beim Rendern einer Seite unten angezeigt, können diese gefunden werden, indem ein Breakpoint bei MessageUtils.getExceptionMessage(String messageId, Object... params) gesetzt wird.Annotation Processing#
In den meisten Servlet-Containern werden die JSF-Annotations automatisch verarbeitet, wie @ManagedBean, @SessionScoped und so weiter. Allerdings klappt das nicht immer, wie Beispielsweise bei embedded Tomcat. Dann kann mit folgendem Servlet-Context-Parameter abgeholfen werden:<context-param> <param-name>com.sun.faces.injectionProvider</param-name> <param-value>com.sun.faces.vendor.WebContainerInjectionProvider</param-value> </context-param>