对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-doc.cadn.net.cn

自由标记

Apache FreeMarker 是一个模板引擎,用于生成任何 从 HTML 到电子邮件等的文本输出类型。Spring Framework 内置了 用于将 Spring MVC 与 FreeMarker 模板一起使用的集成。spring-doc.cadn.net.cn

View 配置

以下示例显示了如何将 FreeMarker 配置为视图技术:spring-doc.cadn.net.cn

@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;
	}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.freeMarker()
	}

	// Configure FreeMarker...

	@Bean
	fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
		setTemplateLoaderPath("/WEB-INF/freemarker")
	}
}

以下示例显示了如何在 XML 中配置相同的内容:spring-doc.cadn.net.cn

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

或者,您也可以声明FreeMarkerConfigurerbean 用于完全控制所有 属性,如下例所示:spring-doc.cadn.net.cn

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

您的模板需要存储在FreeMarkerConfigurer如前面的示例所示。给定上述配置,如果您的控制器 返回视图名称welcome中,解析程序会查找/WEB-INF/freemarker/welcome.ftl模板。spring-doc.cadn.net.cn

FreeMarker 配置

您可以将 FreeMarker 的 'Settings' 和 'SharedVariables' 直接传递给 FreeMarkerConfiguration对象(由 Spring 管理)通过设置适当的 bean 属性FreeMarkerConfigurer豆。这freemarkerSettingsproperty 需要 一个java.util.Propertiesobject 和freemarkerVariables属性需要java.util.Map.以下示例演示如何使用FreeMarkerConfigurer:spring-doc.cadn.net.cn

<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-doc.cadn.net.cn

表单处理

Spring 提供了一个用于 JSP 的标记库,其中包括一个<spring:bind/>元素。此元素主要允许表单显示来自 表单支持对象,并显示来自Validator在 Web 或业务层。Spring 在 FreeMarker 中也支持相同的功能, 具有用于生成表单输入元素本身的附加便捷宏。spring-doc.cadn.net.cn

Bind 宏

一组标准的宏在spring-webmvc.jar文件 FreeMarker,因此它们始终可用于适当配置的应用程序。spring-doc.cadn.net.cn

Spring 模板库中定义的一些宏被认为是内部的 (私有),但宏定义中不存在此类范围,因此所有宏都可见 调用代码和用户模板。以下各节仅重点介绍宏 您需要直接从模板中调用。如果您想查看宏代码 直接调用该文件spring.ftl,并且位于org.springframework.web.servlet.view.freemarker包。spring-doc.cadn.net.cn

简单绑定

在基于 FreeMarker 模板的 HTML 表单中,这些模板充当 Spring MVC 的表单视图 controller 中,您可以使用类似于以下示例的代码绑定到字段值和 显示每个输入字段的错误消息的方式与 JSP 等效项类似。这 以下示例显示了personForm视图:spring-doc.cadn.net.cn

<!-- 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 对象上的字段名称。你 也可以使用嵌套字段,例如command.address.street.这bindmacro 假定 默认 HTML 转义行为,由ServletContext参数defaultHtmlEscapeweb.xml.spring-doc.cadn.net.cn

宏的另一种形式称为<@spring.bindEscaped>采用第二个参数 显式指定是否应在状态错误中使用 HTML 转义 消息或值。您可以将其设置为truefalse根据需要。附加表格 处理宏简化了 HTML 转义的使用,您应该使用这些宏 尽可能。它们将在下一节中解释。spring-doc.cadn.net.cn

输入宏

FreeMarker 的其他便捷宏简化了装订和表单生成 (包括验证错误显示)。永远没有必要使用这些宏来 生成表单输入字段,并且您可以使用简单的 HTML 或直接将它们混合和匹配 调用我们之前突出显示的 Spring 绑定宏。spring-doc.cadn.net.cn

下表显示了 FreeMarker 模板 (FTL) 定义 以及每个参数的参数列表:spring-doc.cadn.net.cn

表 1.宏定义表
FTL 定义

message(根据 code 参数从资源包中输出一个字符串)spring-doc.cadn.net.cn

<@spring.message code/>spring-doc.cadn.net.cn

messageText(根据 code 参数从资源包中输出一个字符串, 回退到 default 参数的值)spring-doc.cadn.net.cn

<@spring.message文本代码、文本/>spring-doc.cadn.net.cn

url(在相对 URL 前面加上应用程序的上下文根)spring-doc.cadn.net.cn

<@spring.url relativeUrl/>spring-doc.cadn.net.cn

formInput(用于收集用户输入的标准输入字段)spring-doc.cadn.net.cn

<@spring.form输入路径、属性、fieldType/>spring-doc.cadn.net.cn

formHiddenInput(用于提交非用户输入的隐藏输入字段)spring-doc.cadn.net.cn

<@spring.formHiddenInput 路径,attributes/>spring-doc.cadn.net.cn

formPasswordInput(用于收集密码的标准输入字段。请注意,没有 value 会填充到此类型的字段中。spring-doc.cadn.net.cn

<@spring.formPasswordInput 路径、attributes/>spring-doc.cadn.net.cn

formTextarea(用于收集较长的自由格式文本输入的大文本字段)spring-doc.cadn.net.cn

<@spring.formText区域路径、attributes/>spring-doc.cadn.net.cn

formSingleSelect(选项的下拉框,让单个 required 值为 selected)spring-doc.cadn.net.cn

<@spring.formSingleSelect 路径、选项、属性/>spring-doc.cadn.net.cn

formMultiSelect(允许用户选择 0 个或多个值的选项列表框)spring-doc.cadn.net.cn

<@spring.formMultiSelect path, options, attributes/>spring-doc.cadn.net.cn

formRadioButtons(一组用于进行单个选择的单选按钮 从可用选项中)spring-doc.cadn.net.cn

<@spring.formRadioButtons 路径、选项分隔符、attributes/>spring-doc.cadn.net.cn

formCheckboxes(一组允许选择 0 或多个值的复选框)spring-doc.cadn.net.cn

<@spring.formCheckboxes 路径、选项、分隔符、attributes/>spring-doc.cadn.net.cn

formCheckbox(单个复选框)spring-doc.cadn.net.cn

<@spring.formCheckbox 路径,attributes/>spring-doc.cadn.net.cn

showErrors(简化绑定字段的验证错误的显示)spring-doc.cadn.net.cn

<@spring.showErrors 分隔符 classOrStyle/>spring-doc.cadn.net.cn

在 FreeMarker 模板中,formHiddenInputformPasswordInput实际上并非 required,因为您可以使用正常的formInput宏, 指定hiddenpassword作为fieldType参数。

上述任何宏的参数都具有一致的含义:spring-doc.cadn.net.cn

  • path:要绑定到的字段的名称(例如,“command.name”)spring-doc.cadn.net.cn

  • options:一个Map可以在输入中选择的所有可用值 田。映射的键表示从表单中 POST 回来的值 并绑定到 Command 对象。针对键存储的 Map 对象是标签 在表单上显示给用户,并且可能与相应的值不同 通过表单发回。通常,此类映射由 控制器。您可以使用任何Mapimplementation 的 Instant,具体取决于所需的行为。 对于严格排序的地图,您可以使用SortedMap(例如TreeMap) 替换为 合适Comparator并且,对于应在插入中返回值的任意 Map order 中使用LinkedHashMapLinkedMapcommons-collections.spring-doc.cadn.net.cn

  • separator:其中多个选项可用作隐蔽元素(单选按钮 或复选框)中,则用于分隔列表中每个字符的字符序列 (例如<br>).spring-doc.cadn.net.cn

  • attributes:要包含在其中的任意标签或文本的附加字符串 HTML 标签本身。此字符串由宏逐字面回显。例如,在textarea字段,您可以提供属性(例如 'rows=“5” cols=“60”'),或者您 可以传递样式信息,例如 'style=“border:1px solid silver”'。spring-doc.cadn.net.cn

  • classOrStyle:对于showErrorsmacro 的 CSS 类的名称,该类的span元素。如果未提供任何信息(或者值为 empty),则错误将包含在<b></b>标签。spring-doc.cadn.net.cn

以下各节概述了宏的示例。spring-doc.cadn.net.cn

输入字段

formInputmacro 将path参数 (command.name) 和额外的attributes参数(在即将到来的示例中为空)。宏以及所有其他形式 generation 宏,对 path 参数执行隐式 Spring 绑定。绑定 在发生新绑定之前保持有效,因此showErrors宏不需要传递 path 参数 — 它对上次为其创建绑定的字段进行作。spring-doc.cadn.net.cn

showErrorsmacro 接受一个 separator 参数(用于 分隔给定字段上的多个错误),并且还接受第二个参数 — this time、类名或 style 属性。请注意,FreeMarker 可以指定 default attributes 参数的值。以下示例演示如何使用formInputshowErrors宏:spring-doc.cadn.net.cn

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

下一个示例显示了表单片段的输出,生成 name 字段并显示 提交表单后出现验证错误,但字段中没有值。验证 通过 Spring 的 Validation 框架发生。spring-doc.cadn.net.cn

生成的 HTML 类似于以下示例:spring-doc.cadn.net.cn

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

formTextarea宏的工作方式与formInput宏并接受相同的 parameter 列表。通常,第二个参数 (attributes) 用于传递样式 information 或rowscols属性textarea.spring-doc.cadn.net.cn

选择字段

您可以使用四个选择字段宏在 您的 HTML 表单:spring-doc.cadn.net.cn

四个宏中的每一个都接受一个Mapof 选项,其中包含表单的值 field 和与该值对应的标签。值和标签可以是 相同。spring-doc.cadn.net.cn

下一个示例是 FTL 中的单选按钮。表单支持对象指定默认值 值为 'London' ,因此无需验证。当表单为 呈现时,可供选择的整个城市列表将作为参考数据提供在 model 替换为 'cityMap' 的下面的清单显示了该示例:spring-doc.cadn.net.cn

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

前面的清单呈现了一行单选按钮,每个按钮对应cityMap,并使用 separator 的 。没有提供其他属性(宏的最后一个参数是 missing)。这""cityMap使用相同的String对于映射中的每个键值对。地图的 键是表单实际提交的POSTrequest 参数。map 值是 标签。在前面的示例中,给定三个知名城市的列表 和表单支持对象中的默认值,则 HTML 类似于以下内容:spring-doc.cadn.net.cn

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>

如果您的应用程序希望通过内部代码处理城市(例如),则可以创建 代码,如下例所示:spring-doc.cadn.net.cn

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

现在,该代码会生成输出,其中 radio 值是相关代码,但 用户仍然会看到对用户更友好的城市名称,如下所示:spring-doc.cadn.net.cn

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.01 compliant 的 v.web.xml文件,作为 由 Spring 的 bind 支持使用。使元素符合 XHTML 或覆盖 默认的 HTML 转义值,您可以在模板中指定两个变量(或在 您的模型,它们对您的模板可见)。指定 它们在模板中是可以稍后在 模板处理为表单中的不同字段提供不同的行为。spring-doc.cadn.net.cn

要切换到标记的 XHTML 合规性,请指定true对于 模型或上下文变量xhtmlCompliant,如下例所示:spring-doc.cadn.net.cn

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

处理此指令后,Spring 宏生成的任何元素现在都是 XHTML 顺从的。spring-doc.cadn.net.cn

以类似的方式,您可以为每个字段指定 HTML 转义,如下例所示:spring-doc.cadn.net.cn

<#-- 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 -->