Hier sind einige Informationen über JSF 2 gespeichert.
<?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>
<?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>
FacesContext.getCurrentInstance().isValidationFailed();
#{facesContext.validationFailed}
<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> <context-param> <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> <param-value>true</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>
Der Eintrag javax.faces.FACELETS_SKIP_COMMENTS sorgt dafür, dass in XML-Kommentaren "<!-- Comment -->" keine EL-Expressions ausgewertet werden. Wird dieses Konfiguration nicht angegeben, kann es zu schwer auffindbaren Fehlern kommen.
<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.
<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.
<context-param> <param-name>com.sun.faces.injectionProvider</param-name> <param-value>com.sun.faces.vendor.WebContainerInjectionProvider</param-value> </context-param>
@Override
public void onComponentCreated(FaceletContext context, UIComponent component, UIComponent parent) {
parent.getChildren().add(component);
}
Ein interessanter Artikel
dazu.
pom.xml:
<dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>3.4-SNAPSHOT</version> </dependency> ... <repositories> <repository> <id>prime-repo</id> <name>Prime Technology Maven Repository</name> <url>http://repository.primefaces.org</url> <layout>default</layout> </repository> </repositories>
web.xml, es ist eine Web-App 3.0 erforderlich:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
...
<servlet>
<servlet-name>Push Servlet</servlet-name>
<servlet-class>org.primefaces.push.PushServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Push Servlet</servlet-name>
<url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
...
</web-app>
Java:
public void someMethod() {
PushContextFactory.getDefault().getPushContext().push("/test", null);
}
Der Eintrag "/test" ist der sogenannte Channel über dem gepusht wird.
Im XHTML wird entweder ein AJAX-Tag verwendet:
<p:socket channel="/test" autoConnect="true"> <p:ajax event="message" update=":push-form:chat"/> </p:socket>
Oder wenn der Update manuell gemacht werden soll, kann auch Javascript verwendet werden:
<p:socket channel="/test" autoConnect="true" onMessage="someMethod"/>
Die Methode wird dann mit einem Parameter "data" aufgerufen, welches dem JSON-Serialisiertem Objekt aus dem Server-Push-Aufruf context.push("/test", data); entspricht.
FacesContextFactory factory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY); LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE); factory.getFacesContext(servletContext, request, response, lifecycle);
Außerhalb von Servlets braucht man den ServletContext, HttpServletRequest und HttpServletResponse, der nicht ganz einfach zu implementieren ist.
Das aktuelle Render Kit kann durch den Request-Parameter "javax.faces.RenderKitId" angesprochen werden, dieser befindet sich als Konstante unter ResponseStateManager.RENDER_KIT_ID_PARAM. Also zum Beispiel die URL:
http://localhost/test/faces/index.xhtml?javax.faces.RenderKitId=test.RenderKit
Dieser Parameter kann auch durch ein Hidden-Field übergeben werden, sodass zum Beispiel Tabellen-, PDF- und andere Downloads generisch für Web-Seiten entwickelt werden können.