Saturday, 27 June 2020

FreeMarker: !: Set default value to missing or null values

A non-existent variable and a variable with null value is same for FreeMarker. By default, FreeMarker throws an error whenever it encounters a missing or null value. If you want to handle these null values, you should convey to FreeMarker explicitly.

 

We can specify default value to a variable using !

 

Syntax

unsafe_expr!default_expr

unsafe_expr!

(unsafe_expr)!default_expr

(unsafe_expr)!

 

For example, see the below snippet.

Welcome ${name!"visitor"}!

 

If the default value is omitted, then it will be empty string and empty sequence and empty hash at the same time.

 

When the field 'name' is missing from data model, template will behave like if user name is the string "visitor". When user name isn't missing, this template behaves exactly like ${name}

 

Similarly, we can set an empty list, if the list variable is null or not present.

 

<#list hobbies![]>

         Your Hobbies are

         <#items as hobby>

                  ${hobby}

         </#items>

</#list>

 

defaultValues.ftl
Welcome ${name!"visitor"}!

<#list hobbies![]>
	Your Hobbies are
	<#items as hobby>
		${hobby}
	</#items>
</#list>

Define ‘FreeMarkerUtil’ class that takes model object and template file as input and merge them.

 

FreeMarkerUtil.java
package com.sample.app.util;

import java.io.StringWriter;
import java.util.Locale;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

public class FreeMarkerUtil {

	private static final Configuration FREE_MARKER_CONFIGURATION = new Configuration(Configuration.VERSION_2_3_30);

	static {
		FREE_MARKER_CONFIGURATION.setClassForTemplateLoading(FreeMarkerUtil.class, "/templates/");
		FREE_MARKER_CONFIGURATION.setDefaultEncoding("UTF-8");
		FREE_MARKER_CONFIGURATION.setLocale(Locale.US);
		FREE_MARKER_CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
		FREE_MARKER_CONFIGURATION.setFallbackOnNullLoopVariable(false);
	}

	public static StringWriter mergeModelAndTemplate(Object modelObject, String ftlFile) throws Exception {
		StringWriter stringWriter = new StringWriter();

		Template template = FREE_MARKER_CONFIGURATION.getTemplate(ftlFile);

		template.process(modelObject, stringWriter);

		return stringWriter;
	}

}

Define DefaultValuesPopulator.

 

DefaultValuesPopulator.java
package com.sample.app;

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import com.sample.app.util.FreeMarkerUtil;

public class DefaultValuesPopulator {
	public static void main(String args[]) throws Exception {

		Map<String, Object> modelObject = new HashMap<String, Object>();
		
		StringWriter stringWriter = FreeMarkerUtil.mergeModelAndTemplate(modelObject, "defaultValues.ftl");
		System.out.println(stringWriter.toString().trim());

	}
}

Output

Welcome visitor!

 

Default value vs non-top level variable

user.name!"no_name"

This will handle if ‘name’ is missing inside user (and returns "no_name" if so), but will not handle if user is missing. That is, the user variable itself must exist, otherwise the template processing will die with error.

 

(user.name)!"no_name"

This will handle if user.name is missing. That is, if ‘user’ is missing, or ‘user’ exists but it does not contain ‘name’, the result will be "no_name", and no error will occur.



Previous                                                    Next                                                    Home

No comments:

Post a Comment