No puede invocar métodos estáticos directamente en EL. EL solo invocará métodos de instancia.
En cuanto a su intento fallido de scriptlet , no puede mezclar scriptlets y EL. Utilice el uno o el otro. Dado que los scriptlets se desaconsejan durante una década, debe ceñirse a una solución exclusiva para EL.
Tiene básicamente 2 opciones (asumiendo que ambas balance
y Calculate#getAmount()
son double
).
Simplemente envuélvalo en un método de instancia.
public double getAmount() {
return Calculate.getAmount(balance);
}
Y utilícelo en su lugar:
Amount: ${row.amount}
O declare Calculate#getAmount()
como una función EL. Primero crea un /WEB-INF/functions.tld
archivo:
<?xml version="1.0" encoding="UTF-8" ?>
<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-jsptaglibrary_2_1.xsd"
version="2.1">
<display-name>Custom Functions</display-name>
<tlib-version>1.0</tlib-version>
<uri>http://example.com/functions</uri>
<function>
<name>calculateAmount</name>
<function-class>com.example.Calculate</function-class>
<function-signature>double getAmount(double)</function-signature>
</function>
</taglib>
Y utilícelo de la siguiente manera:
<%@taglib uri="http://example.com/functions" prefix="f" %>
...
Amount: ${f:calculateAmount(row.balance)}">
Otro enfoque es utilizar Spring SpEL:
<%@taglib prefix="s" uri="http://www.springframework.org/tags" %> <s:eval expression="T(org.company.Calculate).getAmount(row.balance)" var="rowBalance" /> Amount: ${rowBalance}
Si omite opcional
var="rowBalance"
,<s:eval>
se imprimirá el resultado de la expresión en la salida.fuente
'the_string_argument'
, no es necesario bailar con el escape.Si su clase de Java es:
package com.test.ejb.util; public class CommonUtilFunc { public static String getStatusDesc(String status){ if(status.equals("A")){ return "Active"; }else if(status.equals("I")){ return "Inactive"; }else{ return "Unknown"; } } }
Luego puede llamar al método estático 'getStatusDesc' como se muestra a continuación en la página JSP.
Use JSTL useBean para obtener la clase en la parte superior de la página JSP:
<jsp:useBean id="cmnUtilFunc" class="com.test.ejb.util.CommonUtilFunc"/>
Luego llame a la función donde lo requirió usando Expression Language:
<table> <td>${cmnUtilFunc.getStatusDesc('A')}</td> </table>
fuente
Bean como StaticInterface también se puede utilizar
<h:commandButton value="reset settings" action="#{staticinterface.resetSettings}"/>
y frijol
package com.example.common; import com.example.common.Settings; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; @ManagedBean(name = "staticinterface") @ViewScoped public class StaticInterface { public StaticInterface() { } public void resetSettings() { Settings.reset(); } }
fuente
Settings.reset()
es una llamada a un método estático. Lukas propone crear un ManagedBean similar a un contenedor con un método no estático para cada método estático, al que se quiera llamar desde EL. Es una solucion valida.EL 2.2 tiene un mecanismo incorporado de métodos de llamada. Más aquí: sitio de Oracle . Pero no tiene acceso a métodos estáticos. Aunque todavía puede llamarlo a través de la referencia de objeto. Pero uso otra solución, descrita en este artículo: Llamar a un método estático desde EL
fuente
<web-app> → <filter>
).Si está usando struts2, podría usar
<s:var name='myVar' value="%{@package.prefix.MyClass#myMethod('param')}"/>
y luego haga referencia a 'myVar' en el atributo de etiqueta html o html como
${myVar}
fuente
Según la respuesta de @Lukas, puede usar ese bean y llamar al método por reflexión:
@ManagedBean (name = "staticCaller") @ApplicationScoped public class StaticCaller { private static final Logger LOGGER = Logger.getLogger(StaticCaller.class); /** * @param clazz * @param method * @return */ @SuppressWarnings("unchecked") public <E> E call(String clazz, String method, Object... objs){ final ClassLoader loader = Thread.currentThread().getContextClassLoader(); final List<Class<?>> clasesparamList = new ArrayList<Class<?>>(); final List<Object> objectParamList = new ArrayList<Object>(); if (objs != null && objs.length > 0){ for (final Object obj : objs){ clasesparamList.add(obj.getClass()); objectParamList.add(obj); } } try { final Class<?> clase = loader.loadClass(clazz); final Method met = clase.getMethod(method, clasesparamList.toArray(new Class<?>[clasesparamList.size()])); return (E) met.invoke(null, objectParamList.toArray()); } catch (ClassNotFoundException e) { LOGGER.error(e.getMessage(), e); } catch (InvocationTargetException e) { LOGGER.error(e.getMessage(), e); } catch (IllegalAccessException e) { LOGGER.error(e.getMessage(), e); } catch (IllegalArgumentException e) { LOGGER.error(e.getMessage(), e); } catch (NoSuchMethodException e) { LOGGER.error(e.getMessage(), e); } catch (SecurityException e) { LOGGER.error(e.getMessage(), e); } return null; } }
xhtml, en un botón de comando, por ejemplo:
<p:commandButton action="#{staticCaller.call('org.company.Calculate', 'getAmount', row.balance)}" process="@this"/>
fuente
SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (http-localhost/127.0.0.1:8080-5) java.lang.IllegalArgumentException: wrong number of arguments
.<c:forEach var="row" items="${rs.rows}"> ID: ${row.id}<br/> Passwd: ${row.passwd}<br/> <c:set var="balance" value="${row.balance}"/> Amount: <%=Calculate.getAmount(pageContext.getAttribute("balance").toString())%> </c:forEach>
En esta solución, estamos asignando valor (a través de la etiqueta principal) a una variable y luego obtenemos el valor de esa variable en scriplet.
fuente
En Struts2 o Webwork2, puede usar esto:
<s:set name="tourLanguage" value="@foo.bar.TourLanguage@getTour(#name)"/>
Luego haga referencia
#tourLanguage
en su jspfuente