How to access Static Fields in Freemarker FTL

If you defined static fields in Java class and want to use the same in Freemarker (FTL) it is not possible to do so as FTL is not aware of Java objects during rendering. In order to make static fields available to FTL, we need to expose them.

One way of exposing static Java fields to freemarker template is to use them through Model. But if one constant has to be used at multiple places then this would not meet our purpose.

Using Static fields in Spring MVC

In order to use Java static fields in Freemarker in Spring MVC based application, following code snippet can be used:

To access following Java class with static fields:

package net.vibhati;
public class ConstantsEx {
	public final static String NAME = " HELLO WORLD";
}

Add below code in Spring MVC Controller:

import freemarker.ext.beans.BeansWrapper;
...

...
BeansWrapper w = new BeansWrapper(); 
TemplateHashModel statics = w.getStaticModels();
model.addAttribute("statics", statics);

...

In FTL, use JAVA constants as:

${statics["net.vibhati.ConstantsEx"].NAME}

The TemplateHashModel returned from BeanWrapper.getStaticModels, Exposes all static methods and static fields(both final and non-final, using reflection). Now we can add this hashmodel to our Model, as illustrated above. And use it directly in FTL then.

An alternate way to do this is to prepare the TemplateHashModel in a custom filter or Spring Interceptors, so that it becomes common to all the requests(or to the url pattern specified in our custom filter).

This can be implemented is Spring in almost the same manner as explained below for Struts.

Using Static fields in Struts

As MODEL is not available,

In a custom filter, we put our TemplateHashModel in request (this custom filter should be before the Struts 2 filter):

The Java constant class that we need to access in FTL:

package net.vibhati;

public class ConstantsEx {
	public static final String NAME = "Hello World";
}

Just make a custom filter(in this case, MyFilter.java) and put our logic in doFilter():

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	    BeansWrapper bw = StrutsBeanWrapper.getDefaultInstance();
	    TemplateHashModel statics = bw.getStaticModels(); 
	    request.setAttribute("statics", statics); 
	    chain.doFilter(request, response);
		
}

In FTL, now we can use “statics” as below:

${statics["net.vibhati.ConstantsEx"].NAME}

How to configure our custom filter in web.xml:

<filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>net.vibhati.interceptor.MyFilter</filter-class>
       
 </filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Instead of going all the way and configuring our own filter, we can use OGNL in struts , and get the work done by adding just 1 line in our ftl –

${stack.findValue("@[email protected]") }

Although, All these approaches do have some security threats associated, as we are exposing all static fields to FTL.

Dig in more , to know more ;)

Refer: http://freemarker.sourceforge.net/docs/pgui_misc_beanwrapper.html

Get our Articles via Email. Enter your email address.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.