Nie można wywoływać metod statycznych bezpośrednio w EL. EL będzie wywoływać tylko metody instancji.
Jeśli chodzi o nieudaną próbę użycia skryptletu , nie możesz mieszać skryptletów i EL. Użyj jednego lub drugiego. Ponieważ od ponad dekady zniechęca się do używania skryptów , powinieneś trzymać się rozwiązania tylko dla EL.
Masz w zasadzie 2 opcje (zakładając, że obie są balance
i Calculate#getAmount()
są double
).
Po prostu zawiń go w metodę instancji.
public double getAmount() {
return Calculate.getAmount(balance);
}
I zamiast tego użyj:
Amount: ${row.amount}
Lub zadeklaruj Calculate#getAmount()
jako funkcję EL. Najpierw utwórz /WEB-INF/functions.tld
plik:
<?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>
I użyj go w następujący sposób:
<%@taglib uri="http://example.com/functions" prefix="f" %>
...
Amount: ${f:calculateAmount(row.balance)}">
Innym podejściem jest użycie 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}
Jeśli pominąć opcjonalnie
var="rowBalance"
następnie<s:eval>
drukuje wynik wyrażenia do wyjścia.źródło
'the_string_argument'
- nie trzeba tańczyć z ucieczką.Jeśli Twoja klasa Java to:
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"; } } }
Następnie możesz wywołać metodę statyczną „getStatusDesc”, jak poniżej na stronie JSP.
Użyj useBean JSTL, aby uzyskać klasę u góry strony JSP:
<jsp:useBean id="cmnUtilFunc" class="com.test.ejb.util.CommonUtilFunc"/>
Następnie wywołaj funkcję, w której potrzebujesz, używając języka wyrażeń:
<table> <td>${cmnUtilFunc.getStatusDesc('A')}</td> </table>
źródło
Można również użyć bean jak StaticInterface
<h:commandButton value="reset settings" action="#{staticinterface.resetSettings}"/>
i fasola
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(); } }
źródło
Settings.reset()
to statyczne wywołanie metody. Lukas proponuje utworzenie ManagedBean przypominającego opakowanie z metodą niestatyczną dla każdej metody statycznej, którą chce się wywołać z EL. To prawidłowe rozwiązanie.EL 2.2 ma wbudowany mechanizm wywoływania metod. Więcej tutaj: witryna oracle . Ale nie ma dostępu do metod statycznych. Chociaż możesz nadal wywoływać to poprzez odniesienie do obiektu. Ale używam innego rozwiązania, opisanego w tym artykule: Wywołanie metody statycznej z EL
źródło
<web-app> → <filter>
).Jeśli używasz struts2, możesz użyć
<s:var name='myVar' value="%{@package.prefix.MyClass#myMethod('param')}"/>
a następnie odwołaj się do „myVar” w atrybucie tagu html lub html jako
${myVar}
źródło
Na podstawie odpowiedzi @Lukas możesz użyć tej fasoli i metody wywołania przez refleksję:
@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, do przycisku poleceń, na przykład:
<p:commandButton action="#{staticCaller.call('org.company.Calculate', 'getAmount', row.balance)}" process="@this"/>
źródło
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>
W tym rozwiązaniu przypisujemy wartość (poprzez tag core) do zmiennej, a następnie pobieramy wartość tej zmiennej w scriplecie.
źródło
W Struts2 lub Webwork2 możesz użyć tego:
<s:set name="tourLanguage" value="@foo.bar.TourLanguage@getTour(#name)"/>
Następnie
#tourLanguage
odwołaj się do pliku jspźródło