Hier sind einige Informationen über JSF 2 gespeichert. !Google Richfaces vs Primefaces Trends [{Image src='http://www.google.de/trends/viz?q=richfaces,primefaces&date=all&geo=all&graph=weekly_img&sort=0&sa=N'}] RED = Primefaces, BLUE = Richfaces !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> }}}