此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
自由标记
Apache FreeMarker 是一个模板引擎,用于生成任何 从 HTML 到电子邮件等的文本输出。Spring 框架内置了 将 Spring MVC 与 FreeMarker 模板一起使用的集成。
查看配置
以下示例展示了如何将 FreeMarker 配置为视图技术:
-
Java
-
Kotlin
@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");
configurer.setDefaultCharset(StandardCharsets.UTF_8);
return configurer;
}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {
override fun configureViewResolvers(registry: ViewResolverRegistry) {
registry.freeMarker()
}
// Configure FreeMarker...
@Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("/WEB-INF/freemarker")
setDefaultCharset(StandardCharsets.UTF_8)
}
}
以下示例显示了如何在 XML 中配置相同的内容:
<mvc:annotation-driven/>
<mvc:view-resolvers>
<mvc:freemarker/>
</mvc:view-resolvers>
<!-- Configure FreeMarker... -->
<mvc:freemarker-configurer>
<mvc:template-loader-path location="/WEB-INF/freemarker"/>
</mvc:freemarker-configurer>
或者,您也可以声明FreeMarkerConfigurer
bean 用于完全控制所有
属性,如以下示例所示:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
您的模板需要存储在FreeMarkerConfigurer
如前面的示例所示。给定上述配置,如果您的控制器
返回welcome
,解析器会查找/WEB-INF/freemarker/welcome.ftl
模板。
FreeMarker 配置
您可以将 FreeMarker 的“设置”和“共享变量”直接传递给 FreeMarkerConfiguration
对象(由 Spring 管理)通过设置适当的 bean
属性FreeMarkerConfigurer
豆。这freemarkerSettings
属性要求
一个java.util.Properties
对象,而freemarkerVariables
属性需要java.util.Map
.以下示例显示如何使用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"/>
有关设置和变量的详细信息,请参阅 FreeMarker 文档,因为它们适用于
这Configuration
对象。
表单处理
Spring 提供了一个用于 JSP 的标签库,其中包含一个<spring:bind/>
元素。此元素主要允许表单显示来自
form-backing 对象,并显示来自Validator
在
Web 或业务层。Spring 也支持 FreeMarker 中的相同功能,
具有用于生成表单输入元素本身的额外便利宏。
绑定宏
一组标准宏在spring-webmvc.jar
文件
FreeMarker,因此它们始终可用于适当配置的应用程序。
Spring 模板库中定义的一些宏被认为是内部的
(private),但宏定义中不存在此类作用域,使所有宏都可见
调用代码和用户模板。以下部分仅重点介绍宏
您需要直接从模板中调用。如果您想查看宏代码
直接调用该文件spring.ftl
并且位于org.springframework.web.servlet.view.freemarker
包。
简单绑定
在基于 FreeMarker 模板的 HTML 表单中,这些模板充当 Spring MVC 的表单视图
控制器,可以使用类似于下一个示例的代码绑定到字段值,并且
以与 JSP 等效项类似的方式显示每个输入字段的错误消息。这
以下示例显示了personForm
视图:
<!-- FreeMarker macros have to be imported into a namespace.
We strongly recommend sticking to 'spring'. -->
<#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>
需要一个 'path' 参数,该参数由命令的名称组成
对象(它是 'command',除非你在控制器配置中更改了它)紧跟在后面
按要绑定到的命令对象上的句点和字段名称。你
也可以使用嵌套字段,例如command.address.street
.这bind
宏假定
默认 HTML 转义行为由ServletContext
参数defaultHtmlEscape
在web.xml
.
宏的另一种形式称为<@spring.bindEscaped>
采用第二个参数
明确指定是否应在状态错误中使用 HTML 转义
消息或值。您可以将其设置为true
或false
根据需要。附加表格
处理宏简化了 HTML 转义的使用,您应该使用这些宏
尽可能。下一节将对它们进行解释。
输入宏
FreeMarker 的其他便利宏简化了绑定和表单生成 (包括验证错误显示)。永远不需要使用这些宏来 生成表单输入字段,你可以用简单的HTML或直接混合搭配它们 调用我们之前突出显示的 Spring 绑定宏。
下表显示了 FreeMarker 模板 (FTL) 定义 以及每个参数列表:
宏 | FTL 定义 |
---|---|
|
<@spring.消息代码/> |
|
<@spring.message文本代码,text/> |
|
<@spring.url relativeUrl/> |
|
<@spring.form输入路径、属性、字段类型/> |
|
<@spring.formHiddenInput 路径、属性/> |
|
<@spring.formPasswordInput 路径、属性/> |
|
<@spring.formTextarea 路径、属性/> |
|
<@spring.formSingleSelect 路径、选项、属性/> |
|
<@spring.formMultiSelect 路径、选项、属性/> |
|
<@spring.formRadioButtons 路径、选项分隔符、属性/> |
|
<@spring.formCheckboxes 路径、选项、分隔符、属性/> |
|
<@spring.formCheckbox 路径、属性/> |
|
<@spring.showErrors 分隔符,classOrStyle/> |
在 FreeMarker 模板中,formHiddenInput 和formPasswordInput 实际上并不是
必需的,因为您可以使用普通的formInput 宏, 指定hidden 或password 作为fieldType 参数。 |
上述任何宏的参数都具有一致的含义:
-
path
:要绑定到的字段的名称(例如,“command.name”) -
options
:一个Map
输入中可以选择的所有可用值 田。映射的键表示从表单 POST 回来的值 并绑定到命令对象。根据键存储的映射对象是标签 显示在表单上给用户,可能与相应的值不同 由表格发回。通常,此类地图由 控制器。您可以使用任何Map
实现,具体取决于所需的行为。 对于严格排序的地图,您可以使用SortedMap
(例如TreeMap
) 替换为 合适Comparator
并且,对于应在插入中返回值的任意 Map order,请使用LinkedHashMap
或LinkedMap
从commons-collections
. -
separator
:其中多个选项可作为谨慎元素(单选按钮 或复选框),用于分隔列表中每个字符的字符序列 (例如<br>
). -
attributes
:要包含在其中的任意标记或文本的附加字符串 HTML 标签本身。此字符串由宏字面上回显。例如,在textarea
字段,您可以提供属性(例如 'rows=“5” cols=“60”'),或者您 可以传递样式信息,例如 'style=“border:1px 纯银”'。 -
classOrStyle
:对于showErrors
宏,CSS 类的名称,该span
包装每个错误使用的元素。如果未提供任何信息(或值为 empty),错误被包装在<b></b>
标签。
以下部分概述了宏的示例。
输入字段
这formInput
macro 采用path
参数 (command.name
) 和额外的attributes
参数(在即将到来的示例中为空)。宏以及所有其他形式
生成宏,对路径参数执行隐式 Spring 绑定。绑定
在发生新绑定之前保持有效,因此showErrors
宏不需要将
path 参数 — 它对上次为其创建绑定的字段进行作。
这showErrors
宏采用分隔符参数(用于
分隔给定字段上的多个错误),并且还接受第二个参数——
time,类名或样式属性。请注意,FreeMarker 可以指定默认
属性参数的值。以下示例演示如何使用formInput
和showErrors
宏:
<@spring.formInput "command.name"/>
<@spring.showErrors "<br>"/>
下一个示例显示了表单片段的输出,生成 name 字段并显示 提交表单后出现验证错误,字段中没有值。验证 通过 Spring 的 Validation 框架发生。
生成的 HTML 类似于以下示例:
Name:
<input type="text" name="name" value="">
<br>
<b>required</b>
<br>
<br>
这formTextarea
宏的工作方式与formInput
宏并接受相同的
参数列表。通常,第二个参数 (attributes
) 用于传递样式
information 或rows
和cols
属性textarea
.
选择字段
您可以使用四个选择字段宏在 您的 HTML 表单:
-
formSingleSelect
-
formMultiSelect
-
formRadioButtons
-
formCheckboxes
四个宏中的每一个都接受一个Map
包含表单值的选项
字段和与该值对应的标签。值和标签可以是
相同。
下一个示例是 FTL 中的单选按钮。表单支持对象指定默认值 值为“London”,因此无需验证。当表单是 渲染时,要选择的整个城市列表将作为参考数据提供 model,名称为“cityMap”。以下列表显示了示例:
...
Town:
<@spring.formRadioButtons "command.address.town", cityMap, ""/><br><br>
前面的列表呈现了一行单选按钮,每个值对应cityMap
,并使用
的分隔符。未提供其他属性(宏的最后一个参数为
失踪)。这""
cityMap
使用相同的String
对于映射中的每个键值对。映射的keys 是表单实际提交的内容POST
请求参数。地图值是用户看到的标签。在前面的示例中,给定三个知名城市的列表以及表单支持对象中的默认值,HTML 类似于以下内容:
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>
如果您的应用程序希望通过内部代码(例如)处理城市,您可以创建codes 的映射,并具有合适的键,如以下示例所示:
-
Java
-
Kotlin
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)
}
该代码现在生成输出,其中无线电值是相关代码,但 用户仍然会看到更用户友好的城市名称,如下所示:
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 转义
前面描述的表单宏的默认用法会导致 HTML 元素为 HTML 4.01compliant,并且使用web.xml
文件,作为由 Spring 的绑定支持使用。要使元素符合 XHTML 或覆盖默认的 HTML 转义值,您可以在模板中指定两个变量(或在您的模型中,它们对您的模板可见)。在模板中指定它们的好处是它们可以稍后在模板处理中更改为不同的值,为表单中的不同字段提供不同的行为。
要切换到标记的 XHTML 合规性,请指定值true
对于model 或上下文变量,名为xhtmlCompliant
,如以下示例所示:
<#-- for FreeMarker -->
<#assign xhtmlCompliant = true>
处理此指令后,Spring 宏生成的任何元素现在都是 XHTML 顺从的。
以类似的方式,您可以指定每个字段的 HTML 转义,如以下示例所示:
<#-- 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 -->