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";
}
Code language: Java (java)
Add below code in Spring MVC Controller:
import freemarker.ext.beans.BeansWrapper;
...
...
BeansWrapper w = new BeansWrapper();
TemplateHashModel statics = w.getStaticModels();
model.addAttribute("statics", statics);
...
Code language: Java (java)
In FTL, use JAVA constants as:
${statics["net.vibhati.ConstantsEx"].NAME}
Code language: JavaScript (javascript)
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";
}
Code language: Java (java)
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);
}
Code language: Java (java)
In FTL, now we can use “statics” as below:
${statics["net.vibhati.ConstantsEx"].NAME}
Code language: JavaScript (javascript)
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>
Code language: HTML, XML (xml)
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("@net.vibhati.ConstantsEx@NAME") }
Code language: JavaScript (javascript)
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