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:
@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;
}
}
@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:
macro | Definición FTL |
---|---|
|
<@spring.message code/> |
|
<@spring.messageText code, text/> |
|
<@spring.url relatedUrl/> |
|
<@spring.formInput ruta, atributos, tipo de campo/> |
|
<@spring.formHiddenInput ruta, atributos/> |
|
<@spring.formPasswordRuta de entrada, atributos/> |
|
<@spring. ruta formTextarea, atributos/> |
|
<@spring.formSingleSelect ruta, opciones, atributos/> |
|
<@spring.formMultiSelect ruta, opciones, atributos/ > |
|
<@spring.formRadioButtons ruta, separador de opciones, atributos/> |
|
<@spring.formCheckboxes ruta, opciones, separador, atributos/> |
|
<@ruta spring.formCheckbox, atributos/> |
|
<@spring.showErrors separador, classOrStyle/> |
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 campotextarea
puede pasar atributos (por ejemplo, 'rows="5" cols="60"') o información de estilo, por ejemplo, 'style="border:1px solid silver" '.classOrStyle
: para la macroshowErrors
- 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:
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;
}
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 -->