Apache FreeMarker is a template engine for generating any kind of text output from HTML to email, etc. Spring Framework has built-in integration for using Spring MVC with FreeMarker templates.

View Configuration

The following example shows how to configure FreeMarker as your presentation technology:

Java

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.freeMarker();
    }
    // Configure FreeMarker...
    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("/WEB-INF/freemarker");
        return configurer;
    }
}
Kotlin

@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {
    override fun configureViewResolvers(registry: ViewResolverRegistry) {
        registry.freeMarker()
    }
    // Configure FreeMarker...
    @Bean
    fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
        setTemplateLoaderPath("/WEB-INF/freemarker")
    }
}

The following example shows how to configure the same in XML:


<mvc:annotation-driven/>
<mvc:view-resolvers>
    <mvc:freemarker/>
</mvc:view-resolvers>
            <!-- Configuring FreeMarker... -->
<mvc:freemarker-configurer>
    <mvc:template-loader-path location="/WEB-INF/freemarker"/>
</mvc:freemarker-configurer>

In addition, you can declare a FreeMarkerConfigurer bean for complete control over all properties, like shown in the following example:


<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
</bean>

Your templates should be stored in the directory specified by FreeMarkerConfigurer, as shown in the previous example. Given the previous configuration, if your controller returns the view name welcome, the resolver looks for the pattern /WEB-INF/freemarker/welcome.ftl.

FreeMarker Configuration

It is possible to pass the FreeMarker handler's "Settings" and "SharedVariable" directly to the FreeMarker handler's Configuration object (which is managed by Spring) by setting the appropriate bean properties in the FreeMarkerConfigurer. The freemarkerSettings property requires a java.util.Properties object, and the freemarkerVariables property requires a java.util.Map object. The following example shows how to use FreeMarkerConfigurer:


<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
    <property name="freemarkerVariables">
        <map>
            <entry key="xml_escape" value-ref="fmXmlEscape"/>
        </map>
    </property>
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>

Details about the settings and variables that apply to the object Configuration, see FreeMarker documentation.

Form Handling

Spring provides a library of tags for use in JSP, which contains, among other things, the <spring:bind/>. This element primarily allows forms to display values from underlying form objects and display the results of failed validations from a Validator in the web or business tier. Spring also has support for the same functionality in FreeMarker, with additional convenience macros for generating the form input elements themselves.

Binding macros

The support for the standard set of macros is in the file spring-webmvc.jar for FreeMarker, so they are always available to a suitably configured application.

Some macros defined in Spring templating libraries are considered internal (private), but there is no such restriction in macro definitions , which makes all macros visible to calling code and user templates. The following sections cover only macros that need to be called directly from templates. If you need to view the macro code directly, the file is called spring.ftl and is located in the org.springframework.web.servlet.view.freemarker package.

Simple Binding

In your FreeMarker template-based HTML forms that act as the form view for a Spring MVC controller, you can use code like the following example to bind to field values and output to Error message screen for each input field is similar to the JSP equivalent. The following example shows the personForm view:


<!-- FreeMarker macros must be imported into the namespace.
    We strongly recommend sticking with the "spring" option. -->
<#import "/spring.ftl" as spring/>
<html>
    ...
    <form action="" method="POST">
        Name:
        <@spring.bind "personForm.name"/>
        <input type="text"
               name="${spring.status.expression}"
               value="${spring.status.value?html}"/><br/>
        <#list spring.status.errorMessages as error> <b>${error}</b> <br/> </#list>
        <br />
        ...
        <input type="submit" value="submit"/>
    </form>
    ...
</html>

<@spring.bind> requires a "path" argument, which consists of the name of your command object (this is "command" unless you changed it in the controller configuration), followed by a dot and the name of the command object field you want to bind to. You can also use nested fields, such as command.address.street. The bind macro provides default HTML escape logic, specified by the defaultHtmlEscape parameter of the ServletContext context in web.xml.

An alternative form of the <@spring.bindEscaped> macro takes a second argument that explicitly specifies whether HTML escaping should be used in status detection error messages or values. You can set the value to true or false depending on your need. Additional form macros make HTML escaping easier to use, and you should use these macros whenever possible. These are described in the next section.

Input macros

Additional helper macros for FreeMarker simplify form binding and generation (including displaying validation errors). There is no need to use these macros to create form input fields; they can be mixed and matched using plain HTML or direct calls to the Spring binding macros we covered earlier.

The following table of available macros summarizes the FreeMarker Template definitions (FTL) and a list of parameters that each of them accepts:

Table 6. Macro definitions table
macro FTL Definition

message (outputs a string from the resource localization pack based on a code parameter)

<@spring.message code/>

messageText (outputs a string from the resource localization pack based on the parameter code, returning to the default parameter value)

<@spring.messageText code, text/>

url (relative URL prefix with application context root)

<@spring.url relativeUrl/>

formInput (standard input field for collecting user input)

<@spring.formInput path, attributes, fieldType/>

formHiddenInput (hidden input field for transmitting information that is not entered by the user)

<@spring.formHiddenInput path, attributes/>

formPasswordInput (standard input field for collecting passwords. Note that fields of this type are never populated with any value).

<@spring.formPasswordInput path, attributes/>

formTextarea (large text field for collecting long free-form text)

<@spring. formTextarea path, attributes/>

formSingleSelect (drop-down option window that allows you to select one required value)

<@spring.formSingleSelect path, options, attributes/>

formMultiSelect (an option combo box that allows the user to select 0 or more values)

<@spring.formMultiSelect path, options, attributes/>

formRadioButtons (a set of radio buttons that allow you to make one choice from the available options)

<@spring.formRadioButtons path, options separator, attributes/>

formCheckboxes (set checkboxes that allow you to select 0 or more values)

<@spring.formCheckboxes path, options, separator, attributes/>

formCheckbox (one checkbox)

<@spring.formCheckbox path, attributes/>

showErrors (makes it easier to display validation errors for the associated field)

<@spring.showErrors separator, classOrStyle/>

In FreeMarker templates, formHiddenInput and formPasswordInput are actually not needed, since you can use the regular formInput macro by specifying hidden or password as the value of the fieldType parameter.

The parameters of any of the above macros have a clear meaning:

  • path: name of the field to bind (i.e. "command.name")

  • options: Map of all available values that can be selected in the input field. Map keys are values that are passed back from the form and bound to the command object. The Map objects stored along with the keys are the labels that are displayed on the form to the user and may differ from the corresponding values returned by the form. Typically such a Map is provided by the controller as reference data. You can use any Map implementation depending on the required operating logic. For strictly sorted Maps, you can use a SortedMap (such as a TreeMap) with a suitable Comparator, and for arbitrary Maps that need to return values in insertion order, use a LinkedHashMap or a LinkedMap from commons-collections.

  • separator: If multiple options are available as separate elements (radio buttons or checkboxes), then this parameter represents the sequence of characters used to separate each of them in the list (for example, <br>).

  • attributes: An additional string of arbitrary tags or text to include in the HTML tag itself. This line is repeated letter by the macro. For example, the textarea field can pass attributes (for example, 'rows="5" cols="60"') or style information, for example, 'style="border:1px solid silver"'.

  • classOrStyle: for the macro showErrors - the name of the CSS class that is used in the span element, wrapping each error. If no information is provided (or the value is empty), errors are wrapped in <b></b> tags.

The following sections provide examples of macros.

Input fields

The formInput macro accepts the parameter path(command.name) and an additional parameter attributes (which is empty in the following example). This macro, like all other form generation macros, does an implicit Spring binding to the "path" parameter. The binding remains valid until a new binding is made, so the showErrors macro does not need to pass the path parameter again - it operates on the field for which the binding was last created.

The showErrors macro takes a separator parameter (characters that are used to separate multiple errors in a given field) and also takes a second parameter - this time a class name or style attribute. Note that FreeMarker can set default values for the "attributes" parameter. The following example shows how to use the formInput and showErrors macros:


<@spring.formInput "command.name"/>
<@spring.showErrors "<br>"/>

The following example shows the output of a form fragment with generating a name field and displaying a validation error after how the form was submitted without a value in the field. Validation occurs through the Validation framework in Spring.

The generated HTML is similar to the following example:


Name:
<input type="text" name="name" value="">
<br>
    <b>required</b>
<br>
<br>

The formTextarea macro works the same as the formInput macro, and accepts the same list of parameters. Typically the second parameter (attributes) is used to pass style information or the rows and cols attributes for the textarea.

Select Fields

You can use four select field macros to generate regular UI value selection inputs in your HTML forms :

  • formSingleSelect

  • formMultiSelect

  • formRadioButtons

  • formCheckboxes

Each of the four macros accepts a Map option, which contains a value for the form field and a label corresponding to that value. The value and label can be the same.

The following example concerns radio buttons in FTL. The underlying form object sets this field to a default value of "London", so no validation is required. When the form is displayed, the entire list of cities to select is provided as reference data in the model under the name "cityMap". The following listing shows an example:


...
Town:
<@spring.formRadioButtons "command.address.town", cityMap, ""/><br><br>

The previous listing displays a row of radio buttons, one for each value in the cityMap, and uses the delimiter "". No additional attributes are assigned (the last macro parameter is missing). cityMap uses the same String for each key-value pair in the Map. Map keys are what the form actually sends as parameters to the POST request. Map values are the labels that the user sees. In the previous example, given a list of three known cities and a default value in the base form object, the HTML looks like this:


Town:
<input type="radio" name="address.town" value="London">London</input>
<input type="radio" name="address.town" value="Paris" checked="checked">Paris</input>
<input type="radio" name="address.town" value="New York">New York</input>

If your The application assumes working with cities using internal codes (for example), then you can create a Map of codes with the corresponding keys, as shown in the following example:

Java

protected Map<String, ?> referenceData(HttpServletRequest request) throws Exception {
    Map<String, String> cityMap = new LinkedHashMap<>();
    cityMap.put("LDN", "London");
    cityMap.put("PRS", "Paris");
    cityMap.put("NYC", "New York");
    Map<String, Object> model = new HashMap<>();
    model.put("cityMap", cityMap);
    return model;
}
Kotlin

protected fun referenceData(request: HttpServletRequest): Map<String, *> {
    val cityMap = linkedMapOf(
            "LDN" to "London",
            "PRS" to "Paris",
            "NYC" to "New York"
    )
    return hashMapOf("cityMap" to cityMap)
}

The code now outputs data where the switch values are the corresponding codes, but the user still sees more user-friendly city names, as shown below:


Town:
<input type="radio" name="address.town" value="LDN">London</input>
<input type="radio" name="address.town" value="PRS" checked="checked">Paris</input>
<input type="radio" name="address.town" value="NYC">New York</input>

HTML escaping

Using the default form macros described earlier results in HTML elements that conform to the HTML 4.01 standard and use the default HTML escaping value defined in your web.xml file, which is used by the Spring binding support tools. To make elements XHTML compliant, or to override the default HTML escaping value, you can set two variables in your template (or in your model, where your templates see them). The advantage of setting them in templates is that they can be changed to others values later in template processing to provide different logic for different fields in your form.

To switch to XHTML compliant mode for your tags, set the value to true for the model or context variable named xhtmlCompliant, as shown in the following example:


<#-- for FreeMarker -->
<#assign xhtmlCompliant = true>

After processing this directive, all elements created by Spring macros will now be compliant with the XHTML standard.

Similarly, you can specify HTML escaping for each field, as shown in the following example:


<#-- until this point, default HTML escaping is used -->
<#assign htmlEscape = true>
<#-- next field will use HTML escaping -->
<@spring.formInput "command.name"/>
<#assign htmlEscape = false in spring>
<#-- all future fields will be bound with HTML escaping off -->