Apache FreeMarker es un motor de plantillas para generar cualquier tipo de salida de texto desde HTML a correo electrónico, etc. Spring Framework tiene integración incorporada para usar Spring MVC con plantillas de FreeMarker.

Ver configuración

El siguiente ejemplo muestra cómo configurar FreeMarker como su tecnología de presentación:

Java
    
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.freeMarker();
    }
    // Configurar 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()
    }
    // Configurar FreeMarker...
    @Bean
    fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
        setTemplateLoaderPath("/WEB-INF/freemarker")
    }
}

El siguiente ejemplo muestra cómo configurar lo mismo en 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>
    

Además, puede declarar un bean FreeMarkerConfigurer para tener un control completo sobre todas las propiedades. , como se muestra en el siguiente ejemplo:


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

Sus plantillas deben almacenarse en el directorio especificado por FreeMarkerConfigurer, como se muestra en el ejemplo anterior. Dada la configuración anterior, si su controlador devuelve el nombre de vista welcome, el solucionador busca el patrón /WEB-INF/freemarker/welcome.ftl.

Configuración de FreeMarker

Es posible pasar la "Configuración" y la "Variable compartida" del controlador FreeMarker directamente al objeto Configuration del controlador FreeMarker (que es administrado por Spring) configurando el propiedades de bean apropiadas en FreeMarkerConfigurer. La propiedad freemarkerSettings requiere un objeto java.util.Properties y la propiedad freemarkerVariables requiere un objeto java.util.Map objeto. El siguiente ejemplo muestra cómo utilizar 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"/>

Detalles sobre la configuración y las variables que se aplican a el objeto Configuration, consulte la documentación de FreeMarker.

Manejo de formularios

Spring proporciona una biblioteca de etiquetas para usar en JSP, que contiene, entre otras cosas, el <spring:bind/> . Este elemento permite principalmente que los formularios muestren valores de objetos de formulario subyacentes y muestren los resultados de validaciones fallidas de un Validator en el nivel web o empresarial. Spring también admite la misma funcionalidad en FreeMarker, con macros convenientes adicionales para generar los propios elementos de entrada del formulario.

Macros de enlace

El soporte para el conjunto estándar de macros está en el spring-webmvc.jar para FreeMarker, por lo que siempre están disponibles para una aplicación configurada adecuadamente.

Algunas macros definidas en las bibliotecas de plantillas Spring se consideran internas (privadas), pero no No existe tal restricción en las definiciones de macros, lo que hace que todas las macros sean visibles para el código de llamada y las plantillas de usuario. Las siguientes secciones cubren sólo macros que deben llamarse directamente desde plantillas. Si necesita ver el código de la macro directamente, el archivo se llama spring.ftl y se encuentra en el paquete org.springframework.web.servlet.view.freemarker.

Enlace simple

En los formularios HTML basados en plantillas de FreeMarker que actúan como vista de formulario para un controlador Spring MVC, puede usar código como el siguiente ejemplo para enlazar valores de campo. y la salida a la pantalla de mensaje de error para cada campo de entrada es similar al equivalente de JSP. El siguiente ejemplo muestra la vista personForm:


<!-- Las macros de FreeMarker deben importarse al espacio de nombres.
    Recomendamos encarecidamente seguir con la opción "primavera". -->
<#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> requiere un argumento de "ruta", que consta del nombre de su objeto de comando (esto es "comando" a menos que lo haya cambiado en la configuración del controlador), seguido de un punto y el nombre del campo del objeto de comando al que desea vincularse. También puede utilizar campos anidados, como command.address.street. La macro de enlace proporciona una lógica de escape HTML predeterminada, especificada por el parámetro defaultHtmlEscape del contexto ServletContext en web.xml.

Una forma alternativa del <@spring.bindEscaped> macro toma un segundo argumento que especifica explícitamente si el escape HTML debe usarse en mensajes o valores de error de detección de estado. Puede establecer el valor en true o false según sus necesidades. Las macros de formulario adicionales hacen que el escape HTML sea más fácil de usar y debes usar estas macros siempre que sea posible. Se describen en la siguiente sección.

Macros de entrada

Macros auxiliares adicionales para FreeMarker simplifican el enlace y la generación de formularios (incluida la visualización de errores de validación). No es necesario utilizar estas macros para crear campos de entrada de formulario; se pueden mezclar y combinar usando HTML simple o llamadas directas a las macros de enlace Spring que cubrimos anteriormente.

La siguiente tabla de macros disponibles resume las Definiciones de plantillas de FreeMarker (FTL) y una lista de parámetros que acepta cada una de ellas:

Tabla 6. Tabla de definiciones de macros
macro Definición FTL

mensaje (genera una cadena del paquete de localización de recursos según un parámetro de código)

<@spring.message code/>

messageText (salidas una cadena del paquete de localización de recursos basada en el código del parámetro, que regresa al valor del parámetro predeterminado)

<@spring.messageText code, text/>

url (prefijo de URL relativo con raíz de contexto de la aplicación)

<@spring.url relatedUrl/>

formInput (campo de entrada estándar para recopilar entradas del usuario)

<@spring.formInput ruta, atributos, tipo de campo/>

formHiddenInput (campo de entrada oculto para transmitir información que no ingresa el usuario)

<@spring.formHiddenInput ruta, atributos/>

formPasswordInput (campo de entrada estándar para recopilar contraseñas. Tenga en cuenta que los campos de este tipo nunca se completan con ningún valor).

<@spring.formPasswordRuta de entrada, atributos/>

formTextarea (campo de texto grande para recopilar texto largo de formato libre)

<@spring. ruta formTextarea, atributos/>

formSingleSelect (ventana de opciones desplegable que le permite seleccionar un valor requerido )

<@spring.formSingleSelect ruta, opciones, atributos/>

formMultiSelect (un cuadro combinado de opciones que permite al usuario seleccionar 0 o más valores)

<@spring.formMultiSelect ruta, opciones, atributos/ >

formRadioButtons (un conjunto de botones de opción que le permiten elegir una opción entre las opciones disponibles)

<@spring.formRadioButtons ruta, separador de opciones, atributos/>

formCheckboxes (establezca casillas de verificación que le permitan seleccionar 0 o más valores)

<@spring.formCheckboxes ruta, opciones, separador, atributos/>

formCheckbox (una casilla de verificación)

<@ruta spring.formCheckbox, atributos/>

showErrors (facilita la visualización de errores de validación para el campo asociado )

<@spring.showErrors separador, classOrStyle/>

En las plantillas de FreeMarker, formHiddenInput y formPasswordInput en realidad no son necesarios, ya que puedes usar el formInput normal macro especificando hidden o password como el valor del parámetro fieldType.

Los parámetros de cualquiera de las macros anteriores tienen un significado claro:

  • path: nombre del campo a vincular (es decir, "command.name")

  • opciones: Map de todos los valores disponibles que se pueden seleccionar en la entrada campo. Las claves de mapa son valores que se devuelven desde el formulario y se vinculan al objeto de comando. Los objetos Map almacenados junto con las claves son las etiquetas que se muestran en el formulario al usuario y pueden diferir de los valores correspondientes devueltos por el formulario. Normalmente, el controlador proporciona dicho mapa como datos de referencia. Puede utilizar cualquier implementación de Map según la lógica operativa requerida. Para mapas estrictamente ordenados, puede usar un SortedMap (como TreeMap) con un comparador adecuado, y para mapas arbitrarios que necesitan devolver valores en orden de inserción, use un LinkedHashMap o un LinkedMap de commons-collections.

  • separador: si hay varias opciones disponibles como elementos separados (botones de opción o casillas de verificación), entonces este parámetro representa la secuencia de caracteres utilizados para separar cada una de ellas en la lista (por ejemplo, <br>).

  • attributes: una cadena adicional de etiquetas o texto arbitrarios para incluir en la propia etiqueta HTML. Esta línea la repite la macro letra por letra. Por ejemplo, el campo textarea puede pasar atributos (por ejemplo, 'rows="5" cols="60"') o información de estilo, por ejemplo, 'style="border:1px solid silver" '.

  • classOrStyle: para la macro showErrors - el nombre de la clase CSS que se utiliza en el elementospan, envolviendo cada error. Si no se proporciona información (o el valor está vacío), los errores se incluyen en etiquetas <b></b>.

Las siguientes secciones proporcionan ejemplos de macros.

Campos de entrada

La macro formInput acepta el parámetro path(command.name) y un parámetro adicional attributes (que está vacío en el siguiente ejemplo). Esta macro, como todas las demás macros de generación de formularios, realiza un enlace Spring implícito al parámetro "ruta". El enlace sigue siendo válido hasta que se realiza un nuevo enlace, por lo que la macro showErrors no necesita pasar el parámetro de ruta nuevamente: opera en el campo para el cual se creó el enlace por última vez.

La macro showErrors toma un parámetro separador (caracteres que se usan para separar múltiples errores en un campo determinado) y también toma un segundo parámetro, esta vez un nombre de clase o atributo de estilo. Tenga en cuenta que FreeMarker puede establecer valores predeterminados para el parámetro "atributos". El siguiente ejemplo muestra cómo utilizar las macros formInput y showErrors:


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

El siguiente ejemplo muestra la salida de un fragmento de formulario generando un campo de nombre y mostrando un error de validación después de cómo se envió el formulario sin un valor en el campo. La validación se produce a través del marco de Validación en Spring.

El HTML generado es similar al siguiente ejemplo:


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

La macro formTextarea funciona igual que la macro formInput y acepta la misma lista de parámetros. Normalmente, el segundo parámetro (attributes) se utiliza para pasar información de estilo o los atributos rows y cols para el textarea.

Seleccionar campos

Puede utilizar cuatro macros de campo de selección para generar entradas de selección de valores de UI regulares en sus formularios HTML:

  • formSingleSelect

  • formMultiSelect

  • formRadioButtons

  • formCheckboxes

Cada una de las cuatro macros acepta una opción Map, que contiene un valor para el campo del formulario y una etiqueta correspondiente a ese valor. El valor y la etiqueta pueden ser los mismos.

El siguiente ejemplo se refiere a botones de opción en FTL. El objeto de formulario subyacente establece este campo en un valor predeterminado de "Londres", por lo que no se requiere validación. Cuando se muestra el formulario, la lista completa de ciudades para seleccionar se proporciona como datos de referencia en el modelo bajo el nombre "cityMap". El siguiente listado muestra un ejemplo:


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

El listado anterior muestra una fila de botones de opción, uno para cada valor en el cityMap, y utiliza el delimitador "". No se asignan atributos adicionales (falta el último parámetro macro). cityMap utiliza la misma String para cada par clave-valor en el mapa. Las claves de mapa son lo que el formulario realmente envía como parámetros a la solicitud POST. Los valores del mapa son las etiquetas que ve el usuario. En el ejemplo anterior, dada una lista de tres ciudades conocidas y un valor predeterminado en el objeto de formulario base, el HTML se ve así:


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

Si su La aplicación supone trabajar con ciudades usando códigos internos (por ejemplo), luego puedes crear un Mapa de códigos con las claves correspondientes, como se muestra en el siguiente ejemplo:

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

El código ahora genera datos donde los valores de cambio son los códigos correspondientes, pero el usuario aún ve nombres de ciudades más fáciles de usar, como se muestra a continuación:


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

Escapado HTML

El uso de las macros de formulario predeterminadas descritas anteriormente da como resultado elementos HTML que cumplen con el estándar HTML 4.01 y utilizan el valor de escape HTML predeterminado definido en su web.xml archivo, que es utilizado por las herramientas de soporte de encuadernación con resorte. Para hacer que los elementos sean compatibles con XHTML, o para anular el valor de escape HTML predeterminado, puede establecer dos variables en su plantilla (o en su modelo, donde las ven sus plantillas). La ventaja de configurarlas en las plantillas es que se pueden cambiar a otros valores más adelante en el procesamiento de la plantilla para proporcionar una lógica diferente para diferentes campos en su formulario.

Para cambiar al modo compatible con XHTML para sus etiquetas, establezca el valor en true para el modelo o variable de contexto denominada xhtmlCompliant, como se muestra en el siguiente ejemplo:

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

Después de procesar esta directiva, todos los elementos creados por las macros Spring ahora cumplirán con el estándar XHTML.

Del mismo modo, puede especificar un escape HTML para cada campo, como se muestra en el siguiente ejemplo:


<#-- hasta este punto, se utiliza el escape HTML predeterminado -->
<#assign htmlEscape = true>
<#-- el siguiente campo utilizará el escape HTML -->
<@spring.formInput "command.name"/>
<#assign htmlEscape = false in spring>
<#-- todos los campos futuros se vincularán con HTML como escape -->