How to call a static method in JSP/EL?

JavaJspEl

Java Problem Overview


I'm new to JSP. I tried connecting MySQL and my JSP pages and it works fine. But here is what I needed to do. I have a table attribute called "balance". Retrieve it and use it to calculate a new value called "amount". (I'm not printing "balance").

 <c:forEach var="row" items="${rs.rows}">
        ID: ${row.id}<br/>
        Passwd: ${row.passwd}<br/>
        Amount: <%=Calculate.getAmount(${row.balance})%>
 </c:forEach>

It seems it's not possible to insert scriptlets within JSTL tags.

Java Solutions


Solution 1 - Java

You cannot invoke static methods directly in EL. EL will only invoke instance methods.

As to your failing scriptlet attempt, you cannot mix scriptlets and EL. Use the one or the other. Since scriptlets are discouraged over a decade, you should stick to an EL-only solution.

You have basically 2 options (assuming both balance and Calculate#getAmount() are double).

  1. Just wrap it in an instance method.

     public double getAmount() {
         return Calculate.getAmount(balance);
     }
    

    And use it instead:

     Amount: ${row.amount}
    

  2. Or, declare Calculate#getAmount() as an EL function. First create a /WEB-INF/functions.tld file:

     <?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>
    

    And use it as follows:

     <%@taglib uri="http://example.com/functions" prefix="f" %>
     ...
     Amount: ${f:calculateAmount(row.balance)}">
    

Solution 2 - Java

Another approach is to use 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}

If you skip optional var="rowBalance" then <s:eval> will print the result of the expression to output.

Solution 3 - Java

If your Java class is:

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";
        }
    }
}

Then you can call static method 'getStatusDesc' as below in JSP page.

Use JSTL useBean to get class at top of the JSP page:

<jsp:useBean id="cmnUtilFunc" class="com.test.ejb.util.CommonUtilFunc"/>

Then call function where you required using Expression Language:

<table>
    <td>${cmnUtilFunc.getStatusDesc('A')}</td>
</table>

Solution 4 - Java

Bean like StaticInterface also can be used

<h:commandButton value="reset settings" action="#{staticinterface.resetSettings}"/>

and bean

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();
    }
}

Solution 5 - Java

EL 2.2 has inbuild mechanism of calling methods. More here: oracle site. But it has no access to static methods. Though you can stil call it's via object reference. But i use another solution, described in this article: Calling a Static Method From EL

Solution 6 - Java

If you're using struts2, you could use

<s:var name='myVar' value="%{@package.prefix.MyClass#myMethod('param')}"/>

and then reference 'myVar' in html or html tag attribute as ${myVar}

Solution 7 - Java

Based on @Lukas answer you can use that bean and call method by reflection:

@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, into a commandbutton for example:

<p:commandButton action="#{staticCaller.call('org.company.Calculate', 'getAmount', row.balance)}" process="@this"/>

Solution 8 - Java

<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>

In this solution, we're assigning value(Through core tag) to a variable and then we're fetching value of that variable in scriplet.

Solution 9 - Java

In Struts2 or Webwork2, you can use this:

<s:set name="tourLanguage" value="@foo.bar.TourLanguage@getTour(#name)"/>

Then reference #tourLanguage in your jsp

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn EipeView Question on Stackoverflow
Solution 1 - JavaBalusCView Answer on Stackoverflow
Solution 2 - Javadma_kView Answer on Stackoverflow
Solution 3 - JavaSahan MarasingheView Answer on Stackoverflow
Solution 4 - JavaLukasView Answer on Stackoverflow
Solution 5 - JavamsangelView Answer on Stackoverflow
Solution 6 - JavadhblahView Answer on Stackoverflow
Solution 7 - JavaJuanView Answer on Stackoverflow
Solution 8 - Javaash9View Answer on Stackoverflow
Solution 9 - Javasendon1982View Answer on Stackoverflow