function - usar - un método de extensión debe definirse en una clase estática no genérica
¿Cómo crear una función EL personalizada para invocar un método estático? (1)
Soy nuevo en JSF 2. Mi pregunta está relacionada con la respuesta de BalusC a esta pregunta jsf2 ajax partes de actualización basadas en parámetros de solicitud Probé el código kickstart BalusC publicado y me encontré con un error de análisis EL:
/nameofpage.xhtml @12,64 rendered="#{bean.panels.contains(''u1'')}"
Error Parsing: #{bean.panels.contains(''u1'')}
Supongo que esto se debe a que no estoy ejecutando un contenedor compatible con Servlet 3.0 / EL 2.2 con un /WEB-INF/web.xml declarado según la especificación de Servlet 3.0. Estoy usando Tomcat 6.
BalusC sugirió en su respuesta para crear una función EL personalizada. ¿Pero cómo logro esto usando una función EL personalizada? ¿O puede solucionarse esto simplemente configurando ciertas partes de mi proyecto?
Debajo está mi web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Primero crea una clase final
con un método public static
que hace exactamente el trabajo que deseas:
package com.example;
import java.util.Collection;
public final class Functions {
private Functions() {
// Hide constructor.
}
public static boolean contains(Collection<Object> collection, Object item) {
return collection.contains(item);
}
}
Luego facelet-taglib
como facelet-taglib
en /WEB-INF/functions.taglib.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
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-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://example.com/functions</namespace>
<function>
<function-name>contains</function-name>
<function-class>com.example.Functions</function-class>
<function-signature>boolean contains(java.util.Collection, java.lang.Object)</function-signature>
</function>
</facelet-taglib>
Luego familarize Facelets con el nuevo taglib en el /WEB-INF/web.xml
existente:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/functions.taglib.xml</param-value>
</context-param>
(nota: si ya tiene javax.faces.FACELETS_LIBRARIES
, puede agregar el nuevo punto y coma separados)
Luego defínalo en el archivo XHTML de Facelets como nuevo espacio de nombres XML:
<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:func="http://example.com/functions"
...
>
Finalmente puedes usarlo como se pretendía:
rendered="#{func:contains(bean.panels, ''u1'')}"
Como una alternativa completamente diferente, también puede incluir JBoss EL en su proyecto. Funciona en Tomcat 6.0 y podrá invocar métodos no buscadores en EL. jboss-el.jar archivo jboss-el.jar en /WEB-INF/lib
y agregue lo siguiente a su web.xml
:
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Desde EL 2.2 hay otro enfoque: crear un bean @ApplicationScoped
con métodos que a su vez se refieran a esas funciones estáticas. Ver también ao Métodos de utilidad en bean con ámbito de la aplicación .