Links
Comment on page

1.9 View技术

Spring MVC中视图技术的使用是可插入的,无论您决定使用Thymeleaf,Groovy标记模板,JSP还是其他技术,主要取决于配置更改。 本章介绍与Spring MVC集成的视图技术。 我们假设您已经熟悉View Resolution。

1.9.1 Thymeleaf

Thymeleaf是一种现代的服务器端Java模板引擎,它强调可以通过双击在浏览器中预览的自然HTML模板,这对于独立处理UI模板(例如,由设计人员)而无需使用非常有用。 正在运行的服务器。 如果要替换JSP,Thymeleaf提供了最广泛的功能集之一,以使这种过渡更加容易。 Thymeleaf是积极开发和维护的。 有关更完整的介绍,请参见Thymeleaf项目主页。
Thymeleaf与Spring MVC的集成由Thymeleaf项目管理。 该配置涉及一些Bean声明,例如ServletContextTemplateResolver,SpringTemplateEngine和ThymeleafViewResolver。 有关更多详细信息,请参见Thymeleaf + Spring。

1.9.2 FreeMarker

Apache FreeMarker是一个模板引擎,用于生成从HTML到电子邮件等的任何类型的文本输出。 Spring框架具有内置的集成,可以将Spring MVC与FreeMarker模板一起使用。
View配置
以下示例显示如何将FreeMarker配置为一种视图技术:
@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;
}
}
以下示例显示了如何在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/"/>
</bean>
您的模板需要存储在上例所示的FreeMarkerConfigurer指定的目录中。 给定上述配置,如果您的控制器返回欢迎的视图名称,则解析器将查找/WEB-INF/freemarker/welcome.ftl模板。
FreeMarker Configuration
您可以通过在FreeMarkerConfigurer bean上设置适当的bean属性,将FreeMarker的“设置”和“ SharedVariables”直接传递给FreeMarker配置对象(由Spring管理)。 freemarkerSettings属性需要一个java.util.Properties对象,而freemarkerVariables属性需要一个java.util.Map。 以下示例显示了如何执行此操作:
<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"/>
有关设置和变量应用于Configuration对象的详细信息,请参见FreeMarker文档。
表格处理
Spring提供了一个供JSP使用的标签库,其中包含一个<spring:bind />元素。该元素主要允许表单显示来自表单支持对象的值,并显示来自Web或业务层中Validator的验证失败的结果。 Spring还支持FreeMarker中的相同功能,并带有用于生成表单输入元素本身的附加便利宏。
绑定宏
spring-webmvc.jar文件中为这两种语言维护了一组标准宏,因此它们始终可用于经过适当配置的应用程序。
Spring库中定义的某些宏被视为内部(私有)宏,但是在宏定义中不存在这种范围,使所有宏对调用代码和用户模板可见。以下各节仅关注您需要在模板中直接调用的宏。如果您希望直接查看宏代码,则该文件名为spring.ftl,位于org.springframework.web.servlet.view.freemarker包中。
简单绑定
在充当Spring MVC控制器的表单视图的HTML表单(vm或ftl模板)中,您可以使用类似于下一个示例的代码绑定到字段值,并以类似于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 "myModelObject.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'参数,该参数由命令对象的名称(除非您在FormController属性中进行了更改,否则为'command')组成,后跟一个句点和字段的名称。您希望绑定到的命令对象。您还可以使用嵌套字段,例如command.address.street。 bind宏假定由web.xml中的ServletContext参数defaultHtmlEscape指定的默认HTML转义行为。
名为<@ spring.bindEscaped>的宏的可选形式带有第二个参数,并明确指定在状态错误消息或值中应使用HTML转义。您可以根据需要将其设置为true或false。附加的表单处理宏可简化HTML转义的使用,并且您应尽可能使用这些宏。下一节将对它们进行说明。
输入宏
两种语言的附加便利宏均简化了绑定和表单生成(包括验证错误显示)。从来没有必要使用这些宏来生成表单输入字段,并且您可以将它们与简单的HTML混合或匹配,或者直接调用我们之前强调的spring绑定宏。
下表可用的宏显示了每个FTL定义和参数列表:
macro
FTL definition
message (output a string from a resource bundle based on the code parameter)
<@spring.message code/>
messageText (output a string from a resource bundle based on the code parameter, falling back to the value of the default parameter)
<@spring.messageText code, text/>
url (prefix a relative URL with the application’s context root)
<@spring.url relativeUrl/>
formInput (standard input field for gathering user input)
<@spring.formInput path, attributes, fieldType/>
formHiddenInput (hidden input field for submitting non-user input)
<@spring.formHiddenInput path, attributes/>
formPasswordInput (standard input field for gathering passwords. Note that no value is ever populated in fields of this type.)
<@spring.formPasswordInput path, attributes/>
formTextarea (large text field for gathering long, freeform text input)
<@spring.formTextarea path, attributes/>
formSingleSelect (drop down box of options that let a single required value be selected)
<@spring.formSingleSelect path, options, attributes/>
formMultiSelect (a list box of options that let the user select 0 or more values)
<@spring.formMultiSelect path, options, attributes/>
formRadioButtons (a set of radio buttons that let a single selection be made from the available choices)
<@spring.formRadioButtons path, options separator, attributes/>
formCheckboxes (a set of checkboxes that let 0 or more values be selected)
<@spring.formCheckboxes path, options, separator, attributes/>
formCheckbox (a single checkbox)
<@spring.formCheckbox path, attributes/>
showErrors (simplify display of validation errors for the bound field)
<@spring.showErrors separator, classOrStyle/>
  • 在FTL(FreeMarker)中,实际上并不需要formHiddenInput和formPasswordInput,因为您可以使用常规的formInput宏,将hidden或password指定为fieldType参数的值。
以上任何宏的参数都具有一致的含义:
  • path:要绑定的字段名称(即“ command.name”)
  • options:可以在输入字段中选择的所有可用值的映射。映射的键表示从表单回发并绑定到命令对象的值。针对键存储的地图对象是在表单上显示给用户的标签,并且可能与表单回发的相应值不同。通常,这种地图由控制器作为参考数据提供。您可以使用任何Map实现,具体取决于所需的行为。对于严格排序的地图,可以将SortedMap(例如TreeMap)与合适的Comparator一起使用;对于应按插入顺序返回值的任意地图,请使用Commons-collection中的LinkedHashMap或LinkedMap。
  • 分隔符:当多个选项可用作离散元素(单选按钮或复选框)时,用于分隔列表中的每个字符的字符序列(例如<br>)。
  • 属性:HTML标记本身包含的任意标记或文本的附加字符串。该字符串实际上是由宏回显的。例如,在textarea字段中,您可以提供属性(例如'rows =“ 5” cols =“ 60”'),也可以传递样式信息,例如'style =“ border:1px solid silver”。
  • classOrStyle:对于showErrors宏,包装每个错误的span元素使用的CSS类的名称。如果未提供任何信息(或该值为空),则错误将包装在<b> </ b>标记中。
以下各节概述了宏的示例(某些在FTL中,有些在VTL中)。两种语言之间存在用法差异的地方,在注解中进行了说明。
输入栏位 formInput宏带有path参数(command.name)和一个附加的attribute参数(在后面的示例中为空)。该宏与所有其他表单生成宏一起,对path参数执行隐式Spring绑定。绑定保持有效,直到发生新的绑定为止,因此showErrors宏无需再次传递path参数。它在最后创建绑定的字段上进行操作。
showErrors宏采用分隔符参数(用于分隔给定字段上的多个错误的字符),并且还接受第二个参数-这次是类名或样式属性。注意,FreeMarker可以为attributes参数指定默认值。下面的示例演示如何使用formInput和showWErrors宏:
<@spring.formInput "command.name"/>
<@spring.showErrors "<br>"/>
下一个示例显示表单片段的输出,生成名称字段,并在提交表单后在字段中没有值的情况下显示验证错误。 验证通过Spring的Validation框架进行。
生成的HTML类似于以下示例:
Name:
<input type="text" name="name" value="">
<br>
<b>required</b>
<br>
<br>
formTextarea宏的工作方式与formInput宏相同,并且接受相同的参数列表。 通常,第二个参数(属性)用于传递样式信息或文本区域的行和列属性。
选择字段
您可以使用四个选择字段宏在HTML表单中生成常见的UI值选择输入:
  • formSingleSelect
  • formMultiSelect
  • formRadioButtons
  • formCheckboxes
四个宏中的每个宏都接受一个选项映射,其中包含表单字段的值和与该值相对应的标签。 值和标签可以相同。
下一个示例是FTL中的单选按钮。 表单支持对象为此字段指定默认值“London”,因此无需验证。 呈现表单时,将在模型中以“ cityMap”为名称提供可供选择的整个城市列表作为参考数据。 以下清单显示了示例:
...
Town:
<@spring.formRadioButtons "command.address.town", cityMap, ""/><br><br>
上面的清单呈现了一行单选按钮,每个单选按钮用于cityMap中的每个值,并使用分隔符“”。 没有提供其他属性(缺少该宏的最后一个参数)。 cityMap对地图中的每个键值对使用相同的String。 地图的键是表单实际作为POSTed请求参数提交的键。 映射值是用户看到的标签。 在前面的示例中,给定三个知名城市的列表以及表单支持对象中的默认值,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>
如果您的应用程序希望通过内部代码处理城市(例如),则可以使用合适的键创建代码地图,如以下示例所示:
protected Map<String, 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, String> model = new HashMap<>();
model.put("cityMap", cityMap);
return model;
}
现在,该代码将生成输出,其中无线电值是相关代码,但是用户仍然可以看到更加用户友好的城市名称,如下所示:
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
前面介绍的表单宏的默认用法将产生符合HTML 4.01的HTML元素,并使用web xml支持中定义的HTML转义默认值(由Spring的绑定支持使用)。 要使元素符合XHTML或覆盖默认的HTML转义值,您可以在模板(或模型中对模板可见的两个变量)中指定两个变量。 在模板中指定它们的优点是,可以在稍后的模板处理中将它们更改为不同的值,以为表单中的不同字段提供不同的行为。
要为您的标记切换到XHTML兼容性,请为名为xhtmlCompliant的模型或上下文变量指定true值,如以下示例所示:
<#-- 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 -->

1.9.3 Groovy Markup

Groovy标记模板引擎主要旨在生成类似XML的标记(XML,XHTML,HTML5等),但是您可以使用它来生成任何基于文本的内容。 Spring框架具有内置的集成,可以将Spring MVC与Groovy标记一起使用。
Groovy标记模板引擎需要Groovy 2.3.1+。
Configuration
以下示例显示了如何配置Groovy标记模板引擎:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.groovy();
}
// Configure the Groovy Markup Template Engine...
@Bean
public GroovyMarkupConfigurer groovyMarkupConfigurer() {
GroovyMarkupConfigurer configurer = new GroovyMarkupConfigurer();
configurer.setResourceLoaderPath("/WEB-INF/");
return configurer;
}
}
以下示例显示了如何在XML中进行配置:
<mvc:annotation-driven/>
<mvc:view-resolvers>
<mvc:groovy/>
</mvc:view-resolvers>
<!-- Configure the Groovy Markup Template Engine... -->
<mvc:groovy-configurer resource-loader-path="/WEB-INF/"/>
Example
与传统的模板引擎不同,Groovy标记依赖于使用构建器语法的DSL。 以下示例显示了HTML页面的示例模板:
yieldUnescaped '<!DOCTYPE html>'
html(lang:'en') {
head {
meta('http-equiv':'"Content-Type" content="text/html; charset=utf-8"')
title('My page')
}
body {
p('This is an example of HTML contents')
}
}

1.9.4 Script Views

Spring框架具有内置的集成,可以将Spring MVC与可以在JSR-223 Java脚本引擎之上运行的任何模板库一起使用。 我们已经在不同的脚本引擎上测试了以下模板库:
Scripting Library
Scripting Engine
Handlebars
Nashorn
Mustache
Nashorn
React
Nashorn
EJS
Nashorn
ERB
JRuby
String templates
Jython
Kotlin Script templating
Kotlin
集成任何其他脚本引擎的基本规则是,它必须实现ScriptEngine和Invocable接口。
Requirements
您需要在类路径上具有脚本引擎,其细节因脚本引擎而异:
  • Java 8+随附了Nashorn JavaScript引擎。 强烈建议使用可用的最新更新版本。
  • 应该将JRuby添加为对Ruby支持的依赖。
  • 应该将Jython添加为对Python支持的依赖项。
  • 应该添加org.jetbrains.kotlin:kotlin-script-util依赖项和包含org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory行的META-INF / services / javax.script.ScriptEngineFactory文件。 有关更多详细信息,请参见此示例。
您需要具有脚本模板库。 针对Javascript的一种方法是通过WebJars。
Script Templates
您可以声明一个ScriptTemplateConfigurer bean来指定要使用的脚本引擎,要加载的脚本文件,调用呈现模板的函数等等。 以下示例使用Mustache模板和Nashorn JavaScript引擎:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.scriptTemplate();
}
@Bean
public ScriptTemplateConfigurer configurer() {
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
configurer.setEngineName("nashorn");
configurer.setScripts("mustache.js");
configurer.setRenderObject("Mustache");
configurer.setRenderFunction("render");
return configurer;
}
}
以下示例显示了XML中的相同排列:
<mvc:annotation-driven/>
<mvc:view-resolvers>
<mvc:script-template/>
</mvc:view-resolvers>
<mvc:script-template-configurer engine-name="nashorn" render-object="Mustache" render-function="render">
<mvc:script location="mustache.js"/>
</mvc:script-template-configurer>
对于Java和XML配置,该控制器看起来没有什么不同,如以下示例所示:
@Controller
public class SampleController {
@GetMapping("/sample")
public String test(Model model) {
model.addObject("title", "Sample title");
model.addObject("body", "Sample body");
return "template";
}
}
以下示例显示了Mustache模板:
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<p>{{body}}</p>
</body>
</html>
使用以下参数调用render函数:
  • String template:模板内容
  • Map model:视图模型
  • RenderingContext renderingContext:RenderingContext,用于访问应用程序上下文,语言环境,模板加载器和URL(自5.0起)
Mustache.render()与该签名本地兼容,因此您可以直接调用它。
如果您的模板技术需要一些自定义,则可以提供一个实现自定义渲染功能的脚本。 例如,Handlerbars需要在使用模板之前先对其进行编译,并且需要使用polyfill来模拟某些服务器端脚本引擎中不可用的浏览器功能。
以下示例显示了如何执行此操作:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.scriptTemplate();
}
@Bean
public ScriptTemplateConfigurer configurer() {
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
configurer.setEngineName("nashorn");
configurer.setScripts("polyfill.js", "handlebars.js", "render.js");
configurer.setRenderFunction("render");
configurer.setSharedEngine(false);
return configurer;
}
}
当您将非线程安全脚本引擎与不是为并发设计的模板库一起使用时,例如,在Nashorn上运行的Handlebars或React,必须将sharedEngine属性设置为false。 在这种情况下,由于此错误,需要Java 8u60或更高版本。
polyfill.js仅定义Handlebars正常运行所需的window对象,如下所示:
var window = {};
这个基本的render.js实现在使用模板之前先对其进行编译。 生产就绪的实现还应该存储任何重用的缓存模板或预编译的模板。 您可以在脚本方面进行操作(并处理所需的任何自定义,例如管理模板引擎配置)。 以下示例显示了如何执行此操作:
function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}

1.9.5 JSP and JSTL

Spring框架具有内置的集成,可以将Spring MVC与JSP和JSTL一起使用。
View Resolvers
使用JSP开发时,可以声明一个InternalResourceViewResolver或ResourceBundleViewResolver bean。
ResourceBundleViewResolver依靠属性文件来定义映射到类和URL的视图名称。 使用ResourceBundleViewResolver,您可以仅使用一个解析器来混合不同类型的视图,如以下示例所示:
<!-- the ResourceBundleViewResolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
</bean>
# And a sample properties file is used (views.properties in WEB-INF/classes):
welcome.(class)=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp
productList.(class)=org.springframework.web.servlet.view.JstlView
productList.url=/WEB-INF/jsp/productlist.jsp
InternalResourceViewResolver也可以用于JSP。 作为最佳实践,我们强烈建议您将JSP文件放在“ WEB-INF”目录下的目录中,以便客户端无法直接访问。
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
JSP与JSTL
使用JSP标准标记库(JSTL)时,必须使用特殊的视图类JstlView,因为JSTL需要一些准备工作,然后I18N功能才能正常工作。
Spring的JSP标签库
如前几章所述,Spring提供了请求参数到命令对象的数据绑定。为了促进结合这些数据绑定功能的JSP页面的开发,Spring提供了一些使事情变得更加容易的标记。所有Spring标记都具有HTML转义功能,以启用或禁用字符转义。
spring-webmvc.jar中包含spring.tld标记库描述符(TLD)。有关单个标签的全面参考,请浏览API参考或查看标签库说明。
Spring的表单标签库
从2.0版开始,Spring使用JSP和Spring Web MVC时,提供了一组全面的数据绑定感知标签,用于处理表单元素。每个标签都支持其对应的HTML标签对应项的属性集,从而使标签变得熟悉且易于使用。标记生成的HTML符合HTML 4.01 / XHTML 1.0。
与其他表单/输入标签库不同,Spring的表单标签库与Spring Web MVC集成在一起,使标签可以访问命令对象和控制器处理的参考数据。正如我们在以下示例中所示,表单标签使JSP易于开发,读取和维护。
我们浏览一下表单标签,并查看一个如何使用每个标签的示例。我们包含了生成的HTML代码段,其中某些标记需要进一步的注解。
Configuration
表单标签库捆绑在spring-webmvc.jar中。库描述符称为spring-form.tld。
要使用此库中的标记,请在JSP页面顶部添加以下指令:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
表单标签
该标签呈现HTML'form'元素,并向内部标签公开绑定路径以进行绑定。 它将命令对象放在PageContext中,以便内部标签可以访问该命令对象。 该库中的所有其他标签都是form标签的嵌套标签。
假设我们有一个名为User的域对象。 它是一个具有firstName和lastName之类的属性的JavaBean。 我们可以将其用作表单控制器的表单支持对象,该表单控制器返回form.jsp。 以下示例显示了form.jsp的外观:
<form:form>
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form:form>
页面控制器从放置在PageContext中的命令对象中检索firstName和lastName值。 继续阅读以了解如何将内部标签与表单标签一起使用的更复杂的示例。
下面的清单显示了生成的HTML,它看起来像标准格式:
<form method="POST">
<table>
<tr>
<td>First Name:</td>
<td><input name="firstName" type="text" value="Harry"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input name="lastName" type="text" value="Potter"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form>
前面的JSP假定表单支持对象的变量名是command。 如果已将表单支持对象以另一个名称(肯定是最佳实践)放入模型中,则可以将表单绑定到命名变量,如以下示例所示:
<form:form modelAttribute="user">
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form:form>
input标签
默认情况下,此标记呈现具有绑定值和type ='text'的HTML输入元素。 有关此标签的示例,请参见表单标签。 您还可以使用HTML5特定类型,例如电子邮件,电话,日期和其他。
checkbox标签
此标记呈现类型设置为复选框的HTML输入标记。
假设我们的用户有喜好,例如通讯订阅和兴趣爱好列表。 以下示例显示了Preferences类:
public class Preferences {
private boolean receiveNewsletter;
private String[] interests;
private String favouriteWord;
public boolean isReceiveNewsletter() {
return receiveNewsletter;
}
public void setReceiveNewsletter(boolean receiveNewsletter) {
this.receiveNewsletter = receiveNewsletter;
}
public String[] getInterests() {
return interests;
}
public void setInterests(String[] interests) {
this.interests = interests;
}
public String getFavouriteWord() {
return favouriteWord;
}
public void setFavouriteWord(String favouriteWord) {
this.favouriteWord = favouriteWord;
}
}
相应的form.jsp可能类似于以下内容:
<form:form>
<table>
<tr>
<td>Subscribe to newsletter?:</td>
<%-- Approach 1: Property is of type java.lang.Boolean --%>
<td><form:checkbox path="preferences.receiveNewsletter"/></td>
</tr>
<tr>
<td>Interests:</td>
<%-- Approach 2: Property is of an array or of type java.util.Collection --%>
<td>
Quidditch: <form:checkbox path="preferences.interests" value="Quidditch"/>
Herbology: <form:checkbox path="preferences.interests" value="Herbology"/>
Defence Against the Dark Arts: <form:checkbox path="preferences.interests" value="Defence Against the Dark Arts"/>
</td>
</tr>
<tr>
<td>Favourite Word:</td>
<%-- Approach 3: Property is of type java.lang.Object --%>
<td>
Magic: <form:checkbox path="preferences.favouriteWord" value="Magic"/>
</td>
</tr>
</table>
</form:form>
复选框标记有三种方法,它们可以满足您所有的复选框需求。
  • 方法一:当绑定值为java.lang.Boolean类型时,如果绑定值为true,则将input(checkbox)标记为已选中。 value属性对应于setValue(Object)value属性的解析值。
  • 方法二:当绑定值的类型为array或java.util.Collection时,如果绑定的Collection中存在已配置的setValue(Object)值,则将input(checkbox)标记为已选中。
  • 方法三:对于任何其他绑定值类型,如果已配置的setValue(Object)等于绑定值,则将input(复选框)标记为已选中。
请注意,无论采用哪种方法,都会生成相同的HTML结构。 以下HTML代码段定义了一些复选框:
<tr>
<td>Interests:</td>
<td>
Quidditch: <input name="preferences.interests" type="checkbox" value="Quidditch"/>
<input type="hidden" value="1" name="_preferences.interests"/>
Herbology: <input name="preferences.interests" type="checkbox" value="Herbology"/>
<input type="hidden" value="1" name="_preferences.interests"/>
Defence Against the Dark Arts: <input name="preferences.interests" type="checkbox" value="Defence Against the Dark Arts"/>
<input type="hidden" value="1" name="_preferences.interests"/>
</td>
</tr>
您可能不希望在每个复选框之后看到其他隐藏字段。如果未选中HTML页面中的复选框,则提交表单后,其值就不会作为HTTP请求参数的一部分发送到服务器,因此我们需要一种解决方法来使HTML中的这个问题生效,以使Spring表单数据绑定生效。 checkbox标记遵循现有的Spring约定,其中包括每个复选框均带有下划线(_)前缀的隐藏参数。通过这样做,您可以有效地告诉Spring“复选框在表单中可见,并且我希望表单数据绑定到我的对象以反映复选框的状态,无论如何。”
checkboxes标签
该标签呈现类型设置为复选框的多个HTML输入标签。
本节以前面的复选框标签节中的示例为基础。有时,您希望不必在JSP页面中列出所有可能的爱好。您宁愿在运行时提供可用选项的列表,然后将其传递给标记。这就是复选框标签的目的。您可以传入包含items属性中可用选项的数组,列表或映射。通常,bound属性是一个集合,因此它可以保存用户选择的多个值。以下示例显示了使用此标记的JSP:
<form:form>
<table>
<tr>
<td>Interests:</td>
<td>
<%-- Property is of an array or of type java.util.Collection --%>
<form:checkboxes path="preferences.interests" items="${interestList}"/>
</td>
</tr>
</table>
</form:form>
本示例假定interestList是一个可用作模型属性的列表,其中包含要从中选择的值的字符串。 如果您使用的是地图,则将地图输入键用作值,并将地图输入的值用作要显示的标签。 您还可以使用自定义对象,在其中您可以通过使用itemValue提供值的属性名称,并通过使用itemLabel提供标签。
radiobutton标签
此标记呈现类型设置为radio的HTML input元素。
典型的用法模式涉及绑定到相同属性但值不同的多个标记实例,如以下示例所示:
<tr>
<td>Sex:</td>
<td>
Male: <form:radiobutton path="sex" value="M"/> <br/>
Female: <form:radiobutton path="sex" value="F"/>
</td>
</tr>
radiobuttons tag
此标记呈现类型设置为radio的多个HTML输入元素。
与checkboxes标记一样,您可能希望将可用选项作为运行时变量传递。 对于此用法,您可以使用单选按钮标签。 您传入包含items属性中可用选项的数组,列表或映射。 如果您使用地图,则将地图输入键用作值,并将地图输入的值用作要显示的标签。 您还可以使用一个自定义对象,在其中您可以通过使用itemValue提供值的属性名称,并通过使用itemLabel提供标签,如以下示例所示:
<tr>
<td>Sex:</td>
<td><form:radiobuttons path="sex" items="${sexOptions}"/></td>
</tr>
password tag
该标签呈现HTML输入标签,其类型设置为具有绑定值的password。
<tr>
<td>Password:</td>
<td>
<form:password path="password"/>
</td>
</tr>
请注意,默认情况下,不显示密码值。 如果确实希望显示密码值,则可以将showPassword属性的值设置为true,如以下示例所示:
<tr>
<td>Password:</td>
<td>
<form:password path="password" value="^76525bvHGq" showPassword="true"/>
</td>
</tr>
select标签
此标记呈现HTML“ select”元素。 它支持将数据绑定到所选选项以及使用嵌套选项和选项标签。
假定用户具有技能列表。 相应的HTML可能如下所示:
<tr>
<td>Skills:</td>
<td><form:select path="skills" items="${skills}"/></td>
</tr>
如果用户的技能是Herbology,则“技能”行的HTML源可能如下:
<tr>
<td>Skills:</td>
<td>
<select name="skills" multiple="true">
<option value="Potions">Potions</option>
<option value="Herbology" selected="selected">Herbology</option>
<option value="Quidditch">Quidditch</option>
</select>
</td>
</tr>
option tag
此标记呈现HTML选项元素。 根据边界值设置为选中状态。 以下HTML显示了其典型输出:
<tr>
<td>House:</td>
<td>
<form:select path="house">
<form:option value="Gryffindor"/>
<form:option value="Hufflepuff"/>
<form:option value="Ravenclaw"/>
<form:option value="Slytherin"/>
</form:select>
</td>
</tr>
如果用户的房屋位于Gryffindor,则“House”行的HTML源代码如下:
<tr>
<td>House:</td>
<td>
<select name="house">
<option value="Gryffindor" selected="selected">Gryffindor</option>
<option value="Hufflepuff">Hufflepuff</option>
<option value="Ravenclaw">Ravenclaw</option>
<option value="Slytherin">Slytherin</option>
</select>
</td>
</tr>
options tag
此标记呈现HTML选项元素的列表。 它基于绑定值设置选定的属性。 以下HTML显示了其典型输出:
<tr>
<td>Country:</td>
<td>
<form:select path="country">
<form:option value="-" label="--Please Select"/>
<form:options items="${countryList}" itemValue="code" itemLabel="name"/>
</form:select>
</td>
</tr>
如果用户居住在英国,则“国家/地区”行的HTML来源如下:
<tr>
<td>Country:</td>
<td>
<select