基于 Servlet API 并部署到 Servlet 容器(三)

基于 Servlet API 并部署到 Servlet 容器(三)

1.10. HTTP 缓存

网络通量

HTTP 缓存可以显著提高 Web 应用程序的性能。HTTP 缓存 围绕响应标头和随后的条件请求 标头(如 and).建议私有(例如浏览器) 以及有关如何缓存和重用响应的公共(例如代理)缓存。使用标题 提出可能导致没有正文的 304 (NOT_MODIFIED) 的有条件请求, 如果内容没有更改。可以看作是更复杂的继承者 标题。​​Cache-Control​​​​Last-Modified​​​​ETag​​​​Cache-Control​​​​ETag​​​​ETag​​​​Last-Modified​

本节介绍Spring Web MVC中可用的与HTTP缓存相关的选项。

1.10.1. ​​CacheControl​

网络通量

缓存控件提供对 配置与标头相关的设置,并被接受为参数 在许多地方:Cache-Control

  • WebContentInterceptor
  • WebContentGenerator
  • 控制器
  • 静态资源

虽然RFC 7234描述了所有可能的内容 响应标头的指令,该类型采用 面向用例的方法,侧重于常见方案:​​Cache-Control​​​​CacheControl​

// Cache for an hour - "Cache-Control: max-age=3600"
CacheControl ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS);

// Prevent caching - "Cache-Control: no-store"
CacheControl ccNoStore = CacheControl.noStore();

// Cache for ten days in public and private caches,
// public caches should not transform the response
// "Cache-Control: max-age=864000, public, no-transform"
CacheControl ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic();

​WebContentGenerator​​还接受更简单的属性(以秒为单位定义) 工作原理如下:​​cachePeriod​

  • Avalue 不会生成响应标头。-1Cache-Control
  • Avalue 通过使用指令来防止缓存。0'Cache-Control: no-store'
  • Anvalue 使用指令将给定的响应缓存几秒钟。n > 0n'Cache-Control: max-age=n'

1.10.2. 控制器

网络通量

控制器可以添加对 HTTP 缓存的显式支持。我们建议这样做,因为需要先计算资源的理论值,然后才能进行比较 针对条件请求标头。控制器可以向 添加标头和设置,如以下示例所示:​​lastModified​​​​ETag​​​​ETag​​​​Cache-Control​​​​ResponseEntity​

@GetMapping("/book/{id}")
public ResponseEntity<Book> showBook(@PathVariable Long id) {

Book book = findBook(id);
String version = book.getVersion();

return ResponseEntity
.ok()
.cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
.eTag(version) // lastModified is also available
.body(book);
}

特定于应用程序的计算。

响应已设置为 304 (NOT_MODIFIED) — 无进一步处理。

继续处理请求。

前面的示例发送一个 304 (NOT_MODIFIED) 响应,如果比较 到条件请求标头表示内容未更改。否则,会将标头添加到响应中。​​ETag​​​​Cache-Control​

您还可以检查控制器中的条件请求标头, 如以下示例所示:

@RequestMapping
public String myHandleMethod(WebRequest request, Model model) {

long eTag = ...

if (request.checkNotModified(eTag)) {
return null;
}

model.addAttribute(...);
return "myViewName";
}

特定于应用程序的计算。

响应已设置为 304 (NOT_MODIFIED) — 无进一步处理。

继续处理请求。

有三种变体可用于检查条件请求与值、值或两者。对于条件请求,您可以将响应设置为 304(NOT_MODIFIED)。对于条件、和,您可以改为设置响应 到 412 (PRECONDITION_FAILED),以防止并发修改。​​eTag​​​​lastModified​​​​GET​​​​HEAD​​​​POST​​​​PUT​​​​DELETE​

1.10.3. 静态资源

网络通量

您应该使用 aand 条件响应标头提供静态资源 以获得最佳性能。请参阅有关配置静态资源的部分。​​Cache-Control​

1.10.4.过滤器​​ETag​

您可以使用 添加从 响应内容,从而节省带宽,但不能节省 CPU 时间。见浅层ETag。​​ShallowEtagHeaderFilter​​​​eTag​

1.11. 查看技术

网络通量

Spring MVC 中视图技术的使用是可插拔的。您是否决定使用 百里香叶、时髦标记模板、JSP 或其他技术主要是 配置更改。本章介绍与Spring MVC集成的视图技术。 我们假设您已经熟悉视图分辨率。

1.11.1. 百里香叶

网络通量

Thymeleaf是一个现代的服务器端Java模板引擎,强调自然HTML 可以通过双击在浏览器中预览的模板,这非常有用 用于对 UI 模板的独立工作(例如,由设计师进行),而无需 正在运行的服务器。如果你想取代JSP,Thymeleaf提供了最 广泛的功能集,使这种过渡更容易。百里香叶很活跃 开发和维护。有关更完整的介绍,请参阅Thymeleaf项目主页。

Thymeleaf与Spring MVC的集成由Thymeleaf项目管理。 该配置涉及一些 Bean 声明,例如、和。 参见百里香叶+春天了解更多详情。​​ServletContextTemplateResolver​​​​SpringTemplateEngine​​​​ThymeleafViewResolver​

1.11.2. 自由标记

网络通量

Apache FreeMarker是一个模板引擎,用于生成任何 从 HTML 到电子邮件和其他文本输出的一种。Spring 框架内置了 集成使用Spring MVC与FreeMarker模板。

查看配置

网络通量

下面的示例演示如何将 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>

或者,您也可以声明 thebean 以完全控制所有 属性,如以下示例所示:​​FreeMarkerConfigurer​

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

自由标记配置

网络通量

您可以通过设置适当的 bean 将 FreeMarker 的“设置”和“共享变量”直接传递给 FreeMarkerobject(由 Spring 管理)。 沂豆上的属性。该属性要求 aobject,并且该属性需要 a。以下示例演示如何使用:​​Configuration​​​​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 的标签库,其中包含 aelement。此元素主要允许窗体显示来自 表单支持对象,并显示来自 ain 的失败验证的结果 网络或业务层。Spring 在 FreeMarker 中也支持相同的功能, 具有用于自己生成表单输入元素的更多便利宏。​​<spring:bind/>​​​​Validator​

绑定宏

网络通量

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

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

简单装订

在基于 FreeMarker 模板的 HTML 表单中,这些模板充当 Spring MVC 的表单视图 控制器,您可以使用类似于下一个示例的代码绑定到字段值和 以与 JSP 等效项类似的方式显示每个输入字段的错误消息。这 以下示例显示 aview:​​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”参数,该参数由命令的名称组成 对象(它是“命令”,除非您在控制器配置中更改了它)跟随 按句点和要绑定到的命令对象上的字段名称。你 也可以使用嵌套字段,例如。宏假定 参数输入指定的默认 HTML 转义行为。​​command.address.street​​​​bind​​​​ServletContext​​​​defaultHtmlEscape​​​​web.xml​

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

输入宏

FreeMarker 的其他便利宏简化了绑定和表单生成 (包括验证错误显示)。永远没有必要使用这些宏来 生成表单输入字段,您可以将它们与简单的 HTML 或直接混合和匹配 调用我们之前强调的 Spring 绑定宏。

下表显示了自由标记模板 (FTL) 定义 以及每个参数列表:

表 6.宏定义表

宏观

整车运输定义

​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.表单隐藏输入路径、属性/>

​formPasswordInput​​(用于收集密码的标准输入字段。请注意,没有 值永远填充在此类型的字段中。

<@spring.formPassword输入路径、属性/>

​formTextarea​​(用于收集长自由格式文本输入的大文本字段)

<@spring.表单文本区域路径、属性/>

​formSingleSelect​​(允许单个所需值的选项的下拉框 已选择)

<@spring.表单单选路径、选项、属性/>

​formMultiSelect​​(允许用户选择 0 个或多个值的选项列表框)

<@spring.表单多选路径、选项、属性/>

​formRadioButtons​​(一组允许进行单个选择的单选按钮 从可用选项)

<@spring.表单单选按钮路径、选项分隔符、属性/>

​formCheckboxes​​(一组允许选择 0 个或多个值的复选框)

<@spring.表单复选框路径、选项、分隔符、属性/>

​formCheckbox​​(单个复选框)

<@spring.表单复选框路径、属性/>

​showErrors​​(简化绑定字段验证错误的显示)

<@spring.showErrors 分隔符、classOrStyle/>

上述任何宏的参数具有一致的含义:

  • ​path​​:要绑定到的字段的名称(即“command.name”)
  • ​options​​:输入中可以从中选择的所有可用值 田。映射的键表示从表单中 POST 返回的值 并绑定到命令对象。针对键存储的映射对象是标签 显示在表单上向用户显示,并且可能与相应的值不同 通过表格回发。通常,此类地图由 控制器。您可以使用任何实现,具体取决于所需的行为。 对于严格排序的地图,您可以将 a(例如 a)与 适合并且,适用于应在插入中返回值的任意映射 订购,使用 aor afrom。MapMapSortedMapTreeMapComparatorLinkedHashMapLinkedMapcommons-collections
  • ​separator​​:多个选项作为离散元素可用(单选按钮 或复选框),用于分隔列表中每个字符的字符序列 (如)。<br>
  • ​attributes​​:要包含在其中的任意标签或文本的附加字符串 HTML 标记本身。此字符串由宏逐字回显。例如,在字段中,您可以提供属性(例如“rows=”5“ cols=”60“'),或者您 可以传递样式信息,例如“style=”border:1px solid silver“”。textarea
  • ​classOrStyle​​:对于宏,包装每个错误的元素使用的 CSS 类的名称。如果未提供任何信息(或值为 空),错误被包装在标签中。showErrorsspan<b></b>

以下各节概述了宏的示例。

输入字段

宏采用参数 () 和一个附加参数(在下面的示例中为空)。宏,以及所有其他形式 生成宏,对路径参数执行隐式 Spring 绑定。绑定 在发生新绑定之前保持有效,因此宏不需要传递 再次 path 参数 — 它对上次为其创建绑定的字段进行操作。​​formInput​​​​path​​​​command.name​​​​attributes​​​​showErrors​

宏采用分隔符参数(用于 分隔给定字段上的多个错误),并且还接受第二个参数 — this 时间,类名或样式属性。请注意,FreeMarker 可以指定默认值 属性参数的值。下面的示例演示如何使用 theandmacros:​​showErrors​​​​formInput​​​​showErrors​

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

下一个示例显示表单片段的输出,生成名称字段并显示 提交表单后出现验证错误,字段中没有值。验证 通过 Spring 的验证框架发生。

生成的 HTML 类似于以下示例:

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

宏的工作方式与宏相同,并接受相同的 参数列表。通常,第二个参数 () 用于传递样式 信息或属性。​​formTextarea​​​​formInput​​​​attributes​​​​rows​​​​cols​​​​textarea​

选择字段

您可以使用四个选择字段宏在 您的 HTML 表单:

  • ​formSingleSelect​
  • ​formMultiSelect​
  • ​formRadioButtons​
  • ​formCheckboxes​

四个宏中的每一个都接受包含表单值的 aof 选项 字段以及与该值对应的标签。值和标签可以是 相同。​​Map​

下一个示例是 FTL 中的单选按钮。表单支持对象指定默认值 此字段的“London”值,因此无需验证。当表单是 呈现后,可供选择的整个城市列表将作为参考数据在 模型以“城市地图”为名。下面的清单显示了该示例:

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

前面的清单呈现了一行单选按钮,每个值对应一个,并使用 的分隔符。不提供其他属性(宏的最后一个参数是 缺失)。对映射中的每个键值对使用相同。地图的 键是表单实际提交为请求参数的内容。地图值为 用户看到的标签。在前面的示例中,给定三个已知城市的列表 和表单支持对象中的默认值,HTML 类似于以下内容:​​cityMap​​​​""​​​​cityMap​​​​String​​​​POST​

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, ?> 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;
}

代码现在生成输出,其中无线电值是相关代码,但 用户仍然会看到更友好的城市名称,如下所示:

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 4.01 兼容并使用 html 转义的默认值在您的文件中定义,如 由 Spring 的绑定支持使用。使元素符合 XHTML 或重写 默认的 HTML 转义值,您可以在模板中指定两个变量(或在 您的模型,它们对您的模板可见)。指定的优势 它们在模板中是,稍后可以在 模板处理,为表单中的不同字段提供不同的行为。​​web.xml​

要切换到标记的 XHTML 合规性,请为 命名的模型或上下文变量,如以下示例所示:​​true​​​​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 -->

1.11.3. 时髦标记

Groovy 标记模板引擎主要旨在生成类似 XML 的标记(XML、XHTML、HTML5 等),但您可以 使用它来生成任何基于文本的内容。Spring 框架有一个内置的 集成,用于将Spring MVC与Groovy Markup一起使用。

配置

下面的示例演示如何配置 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/"/>

与传统的模板引擎不同,Groovy Markup依赖于使用构建器的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.11.4. 脚本视图

网络通量

Spring 框架有一个内置的集成,可以将 Spring MVC 与任何 可以在JSR-223Java 脚本引擎上运行的模板库。我们已经测试了以下内容 不同脚本引擎上的模板库:

脚本库

脚本引擎

车把

纳肖恩

胡子

纳肖恩

反应

纳肖恩

EJS

纳肖恩

再培训局

JRuby

字符串模板

杰通

Kotlin 脚本模板化

科特林

要求

网络通量

您需要在类路径上安装脚本引擎,其详细信息因脚本引擎而异:

  • NashornJavaScript 引擎提供了 爪哇 8+。强烈建议使用可用的最新更新版本。
  • JRuby 应该作为 Ruby支持的依赖项添加。
  • Jython应该作为Python支持的依赖项添加。
  • ​org.jetbrains.kotlin:kotlin-script-util​​应添加依赖项和包含 aline 的文件以支持 Kotlin 脚本。有关更多详细信息,请参阅此示例。META-INF/services/javax.script.ScriptEngineFactoryorg.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory

您需要具有脚本模板库。对于 JavaScript 来说,一种方法是 通过网络罐。

脚本模板

网络通量

您可以声明 abean 来指定要使用的脚本引擎, 要加载的脚本文件、要调用哪个函数来呈现模板等。 以下示例使用 Mustache 模板和 Nashorn JavaScript 引擎:​​ScriptTemplateConfigurer​

爪哇岛

科特林

@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.addAttribute("title", "Sample title");
model.addAttribute("body", "Sample body");
return "template";
}
}

以下示例显示了胡须模板:

<html>
<head>
<title>{{title}}</title>
</head>
<body>
<p>{{body}}</p>
</body>
</html>

使用以下参数调用呈现函数:

  • ​String template​​:模板内容
  • ​Map model​​:视图模型
  • ​RenderingContext renderingContext​​:提供对应用程序上下文、区域设置、模板加载器和 网址(自 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;
}
}

​polyfill.js​​​仅定义 Handlebar 正常运行所需的对象,如下所示:​​window​

var window = {};

此基本实现在使用模板之前对其进行编译。生产就绪型 实现还应存储任何重复使用的缓存模板或预编译模板。 您可以在脚本端执行此操作(并处理您需要的任何自定义 — 管理 例如,模板引擎配置)。以下示例演示如何执行此操作:​​render.js​

function render(template, model) {
var compiledTemplate = Handlebars.compile(template);
return compiledTemplate(model);
}

查看 Spring 框架单元测试、​​Java​​ 和资源, 了解更多配置示例。

1.11.5.JSP 和 JSTL

Spring 框架有一个内置的集成,用于将 Spring MVC 与 JSP 和 JSTL 一起使用。

查看解析程序

使用 JSP 进行开发时,通常会声明 anbean。​​InternalResourceViewResolver​

​InternalResourceViewResolver​​可用于调度到任何 Servlet 资源,但在 特别是对于 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)时,你必须使用一个特殊的视图类,因为JSTL需要一些准备才能像I18N功能一样的东西。 工作。​​JstlView​

Spring 的 JSP 标签库

Spring 提供请求参数到命令对象的数据绑定,如 前几章。促进JSP页面的开发与这些页面 数据绑定功能,Spring 提供了一些标签,使事情变得更加容易。都 Spring 标签具有 HTML 转义功能,可启用或禁用字符转义。

标签库描述符(TLD)包含在中。 有关单个标签的综合参考,请浏览API 参考或查看标签库说明。​​spring.tld​​​​spring-webmvc.jar​

弹簧的表单标签库

从 2.0 版开始,Spring 提供了一套全面的数据绑定感知标签,用于 在使用JSP和Spring Web MVC时处理表单元素。每个标签都支持 其对应的 HTML 标记对应的属性集,使标记 熟悉且直观易用。标记生成的 HTML 符合 HTML 4.01/XHTML 1.0 标准。

与其他表单/输入标签库不同,Spring 的表单标签库集成了 Spring Web MVC,让标签访问命令对象和参考数据 控制器处理。如以下示例所示,表单标签使 JSP 更易于开发、阅读和维护。

我们浏览表单标签,并查看如何使用每个标签的示例。我们有 包括生成的 HTML 代码段,其中某些标记需要进一步注释。

配置

表单标记库捆绑在一起。库描述符是 叫。​​spring-webmvc.jar​​​​spring-form.tld​

要使用此库中的标记,请将以下指令添加到 JSP 的顶部 页:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

其中,要用于此库中的标记的标记名称前缀。​​form​

表单标签

此标记呈现 HTML “form” 元素,并公开内部标记的绑定路径 捆绑。它将命令对象放入以便命令对象可以 可通过内部标记访问。此库中的所有其他标签都是标签的嵌套标签。​​PageContext​​​​form​

假设我们有一个调用的域对象。它是一个具有属性的JavaBean 比如桑德。我们可以将其用作我们的表单支持对象 表单控制器,返回。以下示例显示了可以 肖:​​User​​​​firstName​​​​lastName​​​​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>

从放置在 由页面控制器。继续阅读以查看更复杂的示例 内部标签如何与标签一起使用。​​firstName​​​​lastName​​​​PageContext​​​​form​

下面的清单显示了生成的 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​

此标记呈现具有绑定值的 HTML 元素,并且默认情况下。 有关此标记的示例,请参阅表单标记。您也可以使用 HTML5 特定的类型,例如,,,等。​​input​​​​type='text'​​​​email​​​​tel​​​​date​

标签​​checkbox​

此标记呈现具有设置为的 HTML标记。​​input​​​​type​​​​checkbox​

假设我们有偏好,例如时事通讯订阅和列表 爱好。以下示例显示类:​​User​​​​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>

有三种方法可以处理标签,它们应该可以满足您的所有复选框需求。​​checkbox​

  • 方法一:当绑定值为类型时,标记为好像绑定值是。该属性对应于值属性的解析值。java.lang.Booleaninput(checkbox)checkedtruevaluesetValue(Object)
  • 方法二:当绑定值为typeor时,标记为配置值为: 存在于边界中。arrayjava.util.Collectioninput(checkbox)checkedsetValue(Object)Collection
  • 方法三:对于任何其他绑定值类型,标记为好像配置等于绑定值。input(checkbox)checkedsetValue(Object)

请注意,无论采用哪种方法,都会生成相同的 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 表单数据绑定正常工作。Thetag 遵循包含隐藏参数的现有 Spring 约定 每个复选框都带有下划线 () 前缀。通过这样做,您有效地 告诉 Spring “复选框在表单中可见,我希望我的对象 无论如何,表单数据都会绑定以反映复选框的状态。​​checkbox​​​​_​

标签​​checkboxes​

此标记呈现多个 HTML 标记,并设置为。​​input​​​​type​​​​checkbox​

本节基于上一个标签部分中的示例构建。有时,你更喜欢 不必在JSP页面中列出所有可能的爱好。你宁愿提供 运行时可用选项的列表,并将其传递给标记。那就是 标签的目的。您可以传入包含 an、a 或 a的内容 属性中的可用选项。通常,绑定属性是 集合,以便它可以保存用户选择的多个值。以下示例 显示了使用此标记的 JSP:​​checkbox​​​​checkboxes​​​​Array​​​​List​​​​Map​​​​items​

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

此示例假定 theis 可用作模型属性 包含要从中选择的值的字符串。如果使用 映射条目键用作值,映射条目的值用作 要显示的标签。您还可以使用自定义对象,您可以在其中提供 使用的值的属性名称以及使用标签的属性名称。​​interestList​​​​List​​​​Map​​​​itemValue​​​​itemLabel​

标签​​radiobutton​

此标记呈现一个 HTML元素,其中 set to 。​​input​​​​type​​​​radio​

典型的使用模式涉及绑定到同一属性的多个标记实例 但具有不同的值,如以下示例所示:

<tr>
<td>Sex:</td>
<td>
Male: <form:radiobutton path="sex" value="M"/> <br/>
Female: <form:radiobutton path="sex" value="F"/>
</td>
</tr>
标签​​radiobuttons​

此标记呈现多个 HTML 元素,并设置为 。​​input​​​​type​​​​radio​

与复选框标签一样,您可能希望 将可用选项作为运行时变量传入。对于此用法,您可以使用标签。您传入包含 该物业的可用选项。如果使用 a,则映射输入键为 用作值,地图条目的值用作要显示的标注。 您还可以使用自定义对象,您可以在其中提供值的属性名称 通过使用和标签使用,如以下示例所示:​​radiobuttons​​​​Array​​​​List​​​​Map​​​​items​​​​Map​​​​itemValue​​​​itemLabel​

<tr>
<td>Sex:</td>
<td><form:radiobuttons path="sex" items="${sexOptions}"/></td>
</tr>
标签​​password​

此标记呈现类型设置为绑定值的 HTML标记。​​input​​​​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 “选择”元素。它支持数据绑定到选定的 选项以及嵌套和标签的使用。​​option​​​​options​

假设 a有一个技能列表。相应的 HTML 可能如下所示:​​User​

<tr>
<td>Skills:</td>
<td><form:select path="skills" items="${skills}"/></td>
</tr>

如果技能在草药学中,则“技能”行的HTML源代码可能是 如下:​​User’s​

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

此标记呈现一个 HTML元素。它设置,基于绑定 价值。以下 HTML 显示了它的典型输出:​​option​​​​selected​

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

如果房子在格兰芬多,“学院”行的HTML源代码将是 如下:​​User’s​

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

请注意添加属性。​​selected​

标签​​options​

此标记呈现 HTML 元素的列表。它设置属性, 基于绑定值。以下 HTML 显示了它的典型输出:​​option​​​​selected​

<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源代码如下:​​User​

<tr>
<td>Country:</td>
<td>
<select name="country">
<option value="-">--Please Select</option>
<option value="AT">Austria</option>
<option value="UK" selected="selected">United Kingdom</option>
<option value="US">United States</option>
</select>
</td>
</tr>

请注意添加属性。​​selected​

如前面的示例所示,antag 与 thetag 的组合用法 生成相同的标准 HTML,但允许您在 仅用于显示(它所属的位置)的 JSP,例如 示例:“-- 请选择”。​​option​​​​options​

该属性通常由项对象的集合或数组填充。并引用这些项对象的 Bean 属性,如果 指定。否则,项对象本身将转换为字符串。或者 您可以指定 AOF 项,在这种情况下,映射键被解释为选项 值和映射值对应于选项标签。Ifor(或两者兼而有之) 碰巧也指定了,Item Value 属性适用于映射键,并且 项目标签属性适用于地图值。​​items​​​​itemValue​​​​itemLabel​​​​Map​​​​itemValue​​​​itemLabel​

标签​​textarea​

此标记呈现一个 HTML元素。以下 HTML 显示了它的典型输出:​​textarea​

<tr>
<td>Notes:</td>
<td><form:textarea path="notes" rows="3" cols="20"/></td>
<td><form:errors path="notes"/></td>
</tr>
标签​​hidden​

此标记呈现一个 HTML标记,其中包含绑定值的 theset。要提交 一个未绑定的隐藏值,将 HTMLtag 与 set to 一起使用。 以下 HTML 显示了它的典型输出:​​input​​​​type​​​​hidden​​​​input​​​​type​​​​hidden​

<form:hidden path="house"/>

如果我们选择将值作为隐藏值提交,则 HTML 将如下所示:​​house​

<input name="house" type="hidden" value="Gryffindor"/>
标签​​errors​

此标记在 HTML 元素中呈现字段错误。它提供对错误的访问 在您的控制器中创建或由与 您的控制器。​​span​

假设我们希望在提交表单后显示 andfields 的所有错误消息。我们有一个类实例的验证器 调用,如以下示例所示:​​firstName​​​​lastName​​​​User​​​​UserValidator​

public class UserValidator implements Validator {

public boolean supports(Class candidate) {
return User.class.isAssignableFrom(candidate);
}

public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "required", "Field is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "required", "Field is required.");
}
}

具体如下:​​form.jsp​

<form:form>
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName"/></td>
<%-- Show errors for firstName field --%>
<td><form:errors path="firstName"/></td>
</tr>

<tr>
<td>Last Name:</td>
<td><form:input path="lastName"/></td>
<%-- Show errors for lastName field --%>
<td><form:errors path="lastName"/></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form:form>

如果我们提交一个在 andfields 中具有空值的表单, HTML 将如下所示:​​firstName​​​​lastName​

<form method="POST">
<table>
<tr>
<td>First Name:</td>
<td><input name="firstName" type="text" value=""/></td>
<%-- Associated errors to firstName field displayed --%>
<td><span name="firstName.errors">Field is required.</span></td>
</tr>

<tr>
<td>Last Name:</td>
<td><input name="lastName" type="text" value=""/></td>
<%-- Associated errors to lastName field displayed --%>
<td><span name="lastName.errors">Field is required.</span></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form>

如果我们想显示给定页面的整个错误列表怎么办?下一个示例 显示该标记还支持一些基本的通配符功能。​​errors​

  • ​path="*"​​:显示所有错误。
  • ​path="lastName"​​:显示与字段关联的所有错误。lastName
  • 省略 ifis,仅显示对象错误。path

下面的示例在页面顶部显示错误列表,后跟 字段旁边的特定于字段的错误:

<form:form>
<form:errors path="*" cssClass="errorBox"/>
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName"/></td>
<td><form:errors path="firstName"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName"/></td>
<td><form:errors path="lastName"/></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form:form>

HTML 将如下所示:

<form method="POST">
<span name="*.errors" class="errorBox">Field is required.<br/>Field is required.</span>
<table>
<tr>
<td>First Name:</td>
<td><input name="firstName" type="text" value=""/></td>
<td><span name="firstName.errors">Field is required.</span></td>
</tr>

<tr>
<td>Last Name:</td>
<td><input name="lastName" type="text" value=""/></td>
<td><span name="lastName.errors">Field is required.</span></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes"/>
</td>
</tr>
</table>
</form>

标签库描述符(TLD)包含在中。 有关单个标签的综合参考,请浏览API 参考或查看标签库说明。​​spring-form.tld​​​​spring-webmvc.jar​

HTTP 方法转换

REST的一个关键原则是使用“统一接口”。这意味着所有 可以使用相同的四种 HTTP 方法来操作资源 (URL):获取、放置、发布、 和删除。对于每种方法,HTTP 规范都定义了确切的语义。为 例如,GET应该始终是安全的操作,这意味着它没有副作用, PUT 或 DELETE 应该是幂等的,这意味着您可以重复这些操作 一遍又一遍,但最终结果应该是一样的。虽然HTTP定义了这些 四种方法,HTML只支持两种:GET和POST。 幸运的是,有两种可能 解决方法:您可以使用JavaScript进行PUT或删除,也可以执行POST。 使用“real”方法作为附加参数(建模为 HTML表单)。春天使用了后一种技巧。这 filter 是一个普通的 Servlet 过滤器,因此,它可以与任何 Web框架(不仅仅是Spring MVC)。将此过滤器添加到您的网络.xml,然后发布 使用隐藏参数转换为相应的 HTTP 方法 请求。​​HiddenHttpMethodFilter​​​​method​

为了支持HTTP方法转换,Spring MVC表单标签已更新为支持设置 HTTP 方法。例如,以下代码片段来自宠物诊所示例:

<form:form method="delete">
<p class="submit"><input type="submit" value="Delete Pet"/></p>
</form:form>

前面的示例执行 HTTP POST,其中隐藏了“真正的”DELETE 方法。 请求参数。它被拾取,定义在 web.xml,如以下示例所示:​​HiddenHttpMethodFilter​

<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>petclinic</servlet-name>
</filter-mapping>

以下示例显示了相应的方法:​​@Controller​

@RequestMapping(method = RequestMethod.DELETE)
public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
this.clinic.deletePet(petId);
return "redirect:/owners/" + ownerId;
}
HTML5 标签

弹簧表单标签库允许输入动态属性,这意味着您可以 输入任何特定于 HTML5 的属性。

表单标记支持输入 than 以外的类型属性。这是 旨在允许呈现新的 HTML5 特定输入类型,例如,,,等。请注意,输入不是必需的,因为是默认类型。​​input​​​​text​​​​email​​​​date​​​​range​​​​type='text'​​​​text​

1.11.6. 瓷砖

您可以在 Web 中集成磁贴 - 就像任何其他视图技术一样 使用 Spring 的应用程序。本节从广义上描述如何执行此操作。

依赖

为了能够使用磁贴,您必须添加对磁贴版本 3.0.1 或更高版本的依赖项 及其与项目的传递依赖项。

配置

为了能够使用磁贴,必须使用包含定义的文件对其进行配置 (有关定义和其他磁贴概念的基本信息,请参阅https://tiles.apache.org)。在春季,这是通过使用来完成的。 以下示例配置演示了如何执行此操作:​​TilesConfigurer​​​​ApplicationContext​

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/defs/general.xml</value>
<value>/WEB-INF/defs/widgets.xml</value>
<value>/WEB-INF/defs/administrator.xml</value>
<value>/WEB-INF/defs/customer.xml</value>
<value>/WEB-INF/defs/templates.xml</value>
</list>
</property>
</bean>

前面的示例定义了五个包含定义的文件。文件都是 位于目录中。在初始化时, 加载文件,并初始化定义工厂。之后有 完成后,定义文件中包含的磁贴可用作 春季网络应用程序。为了能够使用这些视图,您必须在Spring中使用任何其他视图技术:通常很方便。​​WEB-INF/defs​​​​WebApplicationContext​​​​ViewResolver​​​​TilesViewResolver​

您可以通过添加下划线来指定特定于区域设置的磁贴定义,然后 区域设置,如以下示例所示:

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/defs/tiles.xml</value>
<value>/WEB-INF/defs/tiles_fr_FR.xml</value>
</list>
</property>
</bean>

使用上述配置,用于具有区域设置的请求, 默认使用 and。​​tiles_fr_FR.xml​​​​fr_FR​​​​tiles.xml​

​UrlBasedViewResolver​

实例化给定的每个视图 解决。以下 Bean 定义了:​​UrlBasedViewResolver​​​​viewClass​​​​UrlBasedViewResolver​

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
</bean>
​SimpleSpringPreparerFactory​​和​​SpringBeanPreparerFactory​

作为一项高级功能,Spring 还支持两个特殊的 Tiles实现。有关如何在磁贴定义文件中使用引用的详细信息,请参阅磁贴文档。​​PreparerFactory​​​​ViewPreparer​

您可以指定基于以下条件自动连线实例 指定的准备器类,应用 Spring 的容器回调以及应用 配置了 Spring BeanPostProcessor。如果 Spring 的上下文范围注释配置具有 已激活,自动检测类中的注释,并且 应用的。请注意,这需要磁贴定义文件中的准备器类,因为 默认值。​​SimpleSpringPreparerFactory​​​​ViewPreparer​​​​ViewPreparer​​​​PreparerFactory​

您可以指定对指定的准备者名称进行操作(改为 类),从 DispatcherServlet 的 应用程序上下文。完整的豆类创建过程由 Spring 控制 在这种情况下,应用程序上下文,允许使用显式依赖关系注入 配置、作用域 Bean 等。请注意,您需要定义一个 Spring Bean 定义 每个准备者名称(在磁贴定义中使用)。以下示例显示 如何在 Abean 上定义属性:​​SpringBeanPreparerFactory​​​​SpringBeanPreparerFactory​​​​TilesConfigurer​

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/defs/general.xml</value>
<value>/WEB-INF/defs/widgets.xml</value>
<value>/WEB-INF/defs/administrator.xml</value>
<value>/WEB-INF/defs/customer.xml</value>
<value>/WEB-INF/defs/templates.xml</value>
</list>
</property>

<!-- resolving preparer names as Spring bean definition names -->
<property name="preparerFactoryClass"
value="org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory"/>

</bean>

1.11.7.RSS 和原子

Bothandinherit from thebase class,分别用于提供 Atom 和 RSS Feed 视图。他们 基于罗马项目,位于 包。​​AbstractAtomFeedView​​​​AbstractRssFeedView​​​​AbstractFeedView​​​​org.springframework.web.servlet.view.feed​

​AbstractAtomFeedView​​需要你实现方法和 (可选)重写方法(默认实现为 空)。以下示例演示如何执行此操作:​​buildFeedEntries()​​​​buildFeedMetadata()​

public class SampleContentAtomView extends AbstractAtomFeedView {

@Override
protected void buildFeedMetadata(Map<String, Object> model,
Feed feed, HttpServletRequest request) {
// implementation omitted
}

@Override
protected List<Entry> buildFeedEntries(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// implementation omitted
}
}

类似的要求适用于实现,如以下示例所示:​​AbstractRssFeedView​

public class SampleContentRssView extends AbstractRssFeedView {

@Override
protected void buildFeedMetadata(Map<String, Object> model,
Channel feed, HttpServletRequest request) {
// implementation omitted
}

@Override
protected List<Item> buildFeedItems(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// implementation omitted
}
}

Theand方法传入HTTP请求,以防万一 您需要访问区域设置。HTTP 响应仅针对以下设置进行传递 Cookie 或其他 HTTP 标头。源会自动写入响应 方法返回后的对象。​​buildFeedItems()​​​​buildFeedEntries()​

有关创建 Atom 视图的示例,请参阅 Alef Arendsen 的 Spring Team 博客条目。

1.11.8.PDF 和 Excel

Spring 提供了返回 HTML 以外的输出的方法,包括 PDF 和 Excel 电子表格。 本节介绍如何使用这些功能。

文档视图简介

HTML 页面并不总是用户查看模型输出的最佳方式, Spring使生成PDF文档或Excel电子表格变得简单。 从模型数据动态。文档是视图,从 具有正确内容类型的服务器,以(希望)使客户端PC能够运行其 电子表格或 PDF 查看器应用程序作为响应。

为了使用 Excel 视图,您需要将 Apache POI 库添加到您的类路径中。 对于PDF生成,您需要添加(最好)OpenPDF库。

PDF 视图

单词列表的简单 PDF 视图可以扩展和实现该方法,如以下示例所示:​​org.springframework.web.servlet.view.document.AbstractPdfView​​​​buildPdfDocument()​

public class PdfWordList extends AbstractPdfView {

protected void buildPdfDocument(Map<String, Object> model, Document doc, PdfWriter writer,
HttpServletRequest request, HttpServletResponse response) throws Exception {

List<String> words = (List<String>) model.get("wordList");
for (String word : words) {
doc.add(new Paragraph(word));
}
}
}

控制器可以从外部视图定义返回此类视图 (按名称引用它)或作为处理程序方法的实例。​​View​

Excel 视图

从 Spring 框架 4.2 开始,作为基础提供 Excel 视图的类。它基于 Apache POI,具有取代过时类的专用子类(和)。​​org.springframework.web.servlet.view.document.AbstractXlsView​​​​AbstractXlsxView​​​​AbstractXlsxStreamingView​​​​AbstractExcelView​

编程模型类似于,中央模板方法和控制器能够从 外部定义(按名称)或作为处理程序方法的实例。​​AbstractPdfView​​​​buildExcelDocument()​​​​View​

1.11.9. 杰克逊

网络通量

Spring 提供对 Jackson JSON 库的支持。

基于杰克逊的 JSON MVC 视图

网络通量

使用杰克逊库的来呈现响应 内容为 JSON。默认情况下,模型图的全部内容(模型图除外 特定于框架的类)编码为 JSON。对于内容 地图需要过滤,可以指定一组特定的模型属性进行编码 通过使用属性。您还可以使用该属性直接提取和序列化单键模型中的值,而不是 而不是作为模型属性的映射。​​MappingJackson2JsonView​​​​ObjectMapper​​​​modelKeys​​​​extractValueFromSingleKeyModel​

您可以根据需要使用杰克逊提供的自定义 JSON 映射 附注。当您需要进一步控制时,您可以注入自定义通过属性,用于需要提供自定义 JSON 的情况 特定类型的序列化程序和反序列化程序。​​ObjectMapper​​​​ObjectMapper​

基于杰克逊的 XML 视图

网络通量

​MappingJackson2XmlView​​使用Jackson XML 扩展将响应内容呈现为 XML。如果模型包含多个条目,则应 显式设置要使用 Bean 属性序列化的对象。如果 模型包含单个条目,它是自动序列化的。​​XmlMapper​​​​modelKey​

您可以根据需要使用 JAXB 或 Jackson 提供的自定义 XML 映射 附注。当您需要进一步控制时,可以注入自定义通过属性,用于自定义 XML 的情况 您需要为特定类型提供序列化程序和解序列化程序。​​XmlMapper​​​​ObjectMapper​

1.11.10.XML 编组

使用 XML(在包中定义)将响应内容呈现为 XML。您可以显式将对象设置为 通过使用 ainstance 的 sbean 属性进行编组。或者 视图循环访问所有模型属性,并封送支持的第一个类型 由。有关包中功能的详细信息,请参阅使用 O/X 映射器封送 XML。​​MarshallingView​​​​Marshaller​​​​org.springframework.oxm​​​​MarshallingView​​​​modelKey​​​​Marshaller​​​​org.springframework.oxm​

1.11.11. XSLT 视图

XSLT 是一种 XML 转换语言,在 Web 中作为视图技术很流行 应用。XSLT 作为视图技术可能是一个不错的选择,如果您的应用程序 自然处理 XML,或者您的模型是否可以轻松转换为 XML。以下 部分显示如何将 XML 文档生成为模型数据并使其转换 Spring Web MVC 应用程序中的 XSLT。

此示例是一个简单的 Spring 应用程序,它在 the 中创建单词列表并将它们添加到模型图中。将返回地图以及视图 我们的 XSLT 视图的名称。有关Spring Web MVC接口的详细信息,请参阅注释控制器。XSLT 控制器将单词列表转换为简单的 XML 文档已准备好进行转换。​​Controller​​​​Controller​

配置是一个简单的Spring Web应用程序的标准配置:MVC配置 必须定义 anbean 和常规 MVC 注释配置。 以下示例演示如何执行此操作:​​XsltViewResolver​

@EnableWebMvc
@ComponentScan
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Bean
public XsltViewResolver xsltViewResolver() {
XsltViewResolver viewResolver = new XsltViewResolver();
viewResolver.setPrefix("/WEB-INF/xsl/");
viewResolver.setSuffix(".xslt");
return viewResolver;
}
}
控制器

我们还需要一个封装我们的词生成逻辑的控制器。

控制器逻辑封装在 aclass 中,其中 处理程序方法定义如下:​​@Controller​

@Controller
public class XsltController {

@RequestMapping("/")
public String home(Model model) throws Exception {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement("wordList");

List<String> words = Arrays.asList("Hello", "Spring", "Framework");
for (String word : words) {
Element wordNode = document.createElement("word");
Text textNode = document.createTextNode(word);
wordNode.appendChild(textNode);
root.appendChild(wordNode);
}

model.addAttribute("wordList", root);
return "home";
}
}

到目前为止,我们只创建了一个 DOM 文档并将其添加到模型图中。请注意,您 也可以将 XML 文件加载为 a,并使用它来代替自定义 DOM 文档。​​Resource​

有可用的软件包可以自动“支配” 一个对象图,但是在 Spring 中,您可以完全灵活地创建 DOM 以您选择的任何方式从您的模型中。这会阻止 XML 播放的转换 模型数据结构中占比太大,这在使用工具时很危险 来管理数字点化进程。

转型

最后,解决“主”XSLT模板文件并合并 DOM 文档放入其中以生成我们的视图。如配置所示,XSLT 模板存在于目录中的文件中 并以文件扩展名结尾。​​XsltViewResolver​​​​XsltViewResolver​​​​war​​​​WEB-INF/xsl​​​​xslt​

下面的示例演示 XSLT 转换:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" omit-xml-declaration="yes"/>

<xsl:template match="/">
<html>
<head><title>Hello!</title></head>
<body>
<h1>My First Words</h1>
<ul>
<xsl:apply-templates/>
</ul>
</body>
</html>
</xsl:template>

<xsl:template match="word">
<li><xsl:value-of select="."/></li>
</xsl:template>

</xsl:stylesheet>

上述转换呈现为以下 HTML:

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello!</title>
</head>
<body>
<h1>My First Words</h1>
<ul>
<li>Hello</li>
<li>Spring</li>
<li>Framework</li>
</ul>
</body>
</html>

1.12. MVC 配置

网络通量

MVC Java 配置和 MVC XML 命名空间提供默认配置 适用于大多数应用程序和用于自定义它的配置 API。

对于配置 API 中不可用的更高级的自定义, 请参阅高级 Java配置和高级 XML 配置。

您不需要了解由 MVC Java 配置创建的底层 bean 和 MVC 命名空间。如果要了解更多信息,请参阅特殊 Bean 类型和Web MVC 配置。

1.12.1. 启用 MVC 配置

网络通量

在 Java 配置中,您可以使用注释来启用 MVC 配置,如以下示例所示:​​@EnableWebMvc​

@Configuration
@EnableWebMvc
public class WebConfig {
}

在 XML 配置中,您可以使用元素启用 MVC 配置,如以下示例所示:​​<mvc:annotation-driven>​

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">

<mvc:annotation-driven/>

</beans>

前面的示例注册了许多Spring MVC基础架构bean并适应依赖关系。 在类路径上可用(例如,JSON、XML 等的有效负载转换器)。

1.12.2. MVC 配置接口

网络通量

在 Java 配置中,您可以实现接口,如 以下示例显示:​​WebMvcConfigurer​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

// Implement configuration methods...
}

在XML中,可以检查的属性和子元素。您可以 查看Spring MVC XML 模式或使用 IDE 的代码完成功能,用于发现哪些属性和 子元素可用。​​<mvc:annotation-driven/>​

1.12.3. 类型转换

网络通量

默认情况下,会安装各种数字和日期类型的格式化程序以及支持 用于自定义 viaandon 字段。​​@NumberFormat​​​​@DateTimeFormat​

要在 Java 配置中注册自定义格式化程序和转换器,请使用以下命令:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addFormatters(FormatterRegistry registry) {
// ...
}
}

要在 XML 配置中执行相同的操作,请使用以下命令:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">

<mvc:annotation-driven conversion-service="conversionService"/>

<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.example.MyConverter"/>
</set>
</property>
<property name="formatters">
<set>
<bean class="org.example.MyFormatter"/>
<bean class="org.example.MyAnnotationFormatterFactory"/>
</set>
</property>
<property name="formatterRegistrars">
<set>
<bean class="org.example.MyFormatterRegistrar"/>
</set>
</property>
</bean>

</beans>

默认情况下,Spring MVC 在解析和格式化日期时会考虑请求 Locale 值。这适用于日期表示为带有“输入”形式的字符串的表单 领域。但是,对于“日期”和“时间”表单字段,浏览器使用定义的固定格式 在 HTML 规范中。对于这种情况,可以按如下方式自定义日期和时间格式:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}

1.12.4. 验证

网络通量

默认情况下,如果存在Bean 验证 在类路径(例如,Hibernate验证器)上,这是 注册为全局验证器,用于与控制器方法参数一起使用。​​LocalValidatorFactoryBean​​​​@Valid​​​​Validated​

在 Java 配置中,您可以定制全局实例,如 以下示例显示:​​Validator​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public Validator getValidator() {
// ...
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">

<mvc:annotation-driven validator="globalValidator"/>

</beans>

请注意,您还可以在本地注册实现,如下所示 示例显示:​​Validator​

@Controller
public class MyController {

@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new FooValidator());
}
}

1.12.5. 拦截器

在 Java 配置中,您可以注册拦截器以应用于传入请求,如 以下示例显示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/admin/**"/>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

1.12.6. 内容类型

网络通量

您可以配置Spring MVC如何从请求中确定请求的媒体类型 (例如,标头、URL 路径扩展名、查询参数等)。​​Accept​

默认情况下,仅选中标头。​​Accept​

如果必须使用基于 URL 的内容类型解析,请考虑使用查询参数 路径扩展策略。请参阅后缀匹配和后缀匹配和 RFD以了解 更多细节。

在 Java 配置中,您可以自定义请求的内容类型解析,如 以下示例显示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.mediaType("json", MediaType.APPLICATION_JSON);
configurer.mediaType("xml", MediaType.APPLICATION_XML);
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>

1.12.7. 消息转换器

网络通量

您可以通过覆盖 configureMessageConverters()(替换 Spring MVC 创建的默认转换器)或覆盖extendMessageConverters()(自定义默认转换器或向默认转换器添加其他转换器​​)​​来自定义 Java 配置。​​HttpMessageConverter​

以下示例添加具有自定义而不是默认的 XML 和杰克逊 JSON 转换器:​​ObjectMapper​

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
.modulesToInstall(new ParameterNamesModule());
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
}
}

在前面的示例中,Jackson2ObjectMapperBuilder用于为两者创建通用配置,并启用缩进、自定义日期格式、 以及杰克逊模块参数名称的注册, 这增加了对访问参数名称的支持(Java 8 中添加的功能)。​​MappingJackson2HttpMessageConverter​​​​MappingJackson2XmlHttpMessageConverter​

此构建器自定义杰克逊的默认属性,如下所示:

  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES已禁用。
  • MapperFeature.DEFAULT_VIEW_INCLUSION被禁用。

如果在类路径中检测到以下已知模块,它还会自动注册这些模块:

  • jackson-datatype-joda:支持 Joda-Time 类型。
  • jackson-datatype-jsr310:支持 Java 8 日期和时间 API 类型。
  • jackson-datatype-jdk8:支持其他Java 8类型,例如。Optional
  • jackson-module-kotlin:支持 Kotlin 类和数据类。

其他有趣的杰克逊模块可用:

  • jackson-datatype-money:支持fortypes(非官方模块)。javax.money
  • jackson-datatype-hibernate:支持特定于Hibernate的类型和属性(包括延迟加载方面)。

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapper"/>
</bean>
<bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter">
<property name="objectMapper" ref="xmlMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
p:indentOutput="true"
p:simpleDateFormat="yyyy-MM-dd"
p:modulesToInstall="com.fasterxml.jackson.module.paramnames.ParameterNamesModule"/>

<bean id="xmlMapper" parent="objectMapper" p:createXmlMapper="true"/>

1.12.8. 视图控制器

这是立即定义 a 的快捷方式 在调用时转发到视图。您可以在没有 Java 控制器的静态情况下使用它 要在视图生成响应之前运行的逻辑。​​ParameterizableViewController​

以下 Java 配置示例将请求转发到名为:​​/​​​​home​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}

以下示例实现了与前面示例相同的目标,但使用 XML,通过 使用元素:​​<mvc:view-controller>​

<mvc:view-controller path="/" view-name="home"/>

如果方法映射到任何 HTTP 方法的 URL,则视图 控制器不能用于处理相同的 URL。这是因为通过 URL 与 带注释的控制器被认为是端点所有权的足够强大的指示,因此 405 (METHOD_NOT_ALLOWED)、415 (UNSUPPORTED_MEDIA_TYPE) 或类似响应可以 发送到客户端以帮助调试。因此,建议避免 在带批注的控制器和视图控制器之间拆分 URL 处理。​​@RequestMapping​

1.12.9. 视图解析器

网络通量

MVC 配置简化了视图解析器的注册。

以下 Java 配置示例配置内容协商视图 通过使用 JSP 和杰克逊作为 JSON 渲染的默认值进行解析:​​View​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.enableContentNegotiation(new MappingJackson2JsonView());
registry.jsp();
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:view-resolvers>
<mvc:content-negotiation>
<mvc:default-views>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</mvc:default-views>
</mvc:content-negotiation>
<mvc:jsp/>
</mvc:view-resolvers>

但请注意,FreeMarker、Tiles、Groovy Markup 和脚本模板也需要 基础视图技术的配置。

MVC 命名空间提供专用元素。以下示例适用于 FreeMarker:

<mvc:view-resolvers>
<mvc:content-negotiation>
<mvc:default-views>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</mvc:default-views>
</mvc:content-negotiation>
<mvc:freemarker cache="false"/>
</mvc:view-resolvers>

<mvc:freemarker-configurer>
<mvc:template-loader-path location="/freemarker"/>
</mvc:freemarker-configurer>

在 Java 配置中,您可以添加相应的 bean, 如以下示例所示:​​Configurer​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.enableContentNegotiation(new MappingJackson2JsonView());
registry.freeMarker().cache(false);
}

@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/freemarker");
return configurer;
}
}

1.12.10. 静态资源

网络通量

此选项提供了一种从基于资源的位置列表中提供静态资源的便捷方法。

在下一个示例中,给定一个以 开头的请求,相对路径为 用于查找和提供相对于 Web 应用程序下的静态资源 根或类路径下。这些资源提供一年的未来 过期以确保最大限度地使用浏览器缓存并减少 HTTP 请求 由浏览器制作。从中推导出信息,以便标头支持 HTTP 条件请求。​​/resources​​​​/public​​​​/static​​​​Last-Modified​​​​Resource#lastModified​​​​"Last-Modified"​

以下清单显示了如何使用 Java 配置执行此操作:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:resources mapping="/resources/**"
location="/public, classpath:/static/"
cache-period="31556926" />

另请参阅静态资源的 HTTP 缓存支持。

资源处理程序还支持资源解析器实现和资源转换器实现链, 可用于创建用于处理优化资源的工具链。

您可以使用基于 MD5 哈希的版本控制资源 URL 根据内容、固定应用程序版本或其他版本计算得出。A(MD5 哈希)是一个不错的选择 — 有一些值得注意的例外,例如 与模块加载器一起使用的 JavaScript 资源。​​VersionResourceResolver​​​​ContentVersionStrategy​

以下示例显示了如何在 Java 配置中使用:​​VersionResourceResolver​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:resources mapping="/resources/**" location="/public/">
<mvc:resource-chain resource-cache="true">
<mvc:resolvers>
<mvc:version-resolver>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>

然后,您可以使用重写 URL 并应用完整的解析器链和 转换器 — 例如,插入版本。MVC 配置提供 abean,以便可以将其注入到其他人中。您还可以使用Thymeleaf,JSP,FreeMarker和其他带有URL标签的URL标签使重写透明 恃。​​ResourceUrlProvider​​​​ResourceUrlProvider​​​​ResourceUrlEncodingFilter​​​​HttpServletResponse#encodeURL​

请注意,当同时使用两者时(例如,用于提供 gzip 或 brotli 编码的资源),并且,您必须按此顺序注册它们。 这可确保始终基于未编码的文件可靠地计算基于内容的版本。​​EncodedResourceResolver​​​​VersionResourceResolver​

对于WebJars,版本化 URL 是推荐和最有效的使用方式。 相关的资源位置是使用 Spring 引导配置的开箱即用(或者可以配置 手动通过),并且不需要添加依赖项。​​/webjars/jquery/1.2.0/jquery.min.js​​​​ResourceHandlerRegistry​​​​org.webjars:webjars-locator-core​

无版本的 URL 支持通过当库存在于类路径上时自动注册,代价是 可能会减慢应用程序启动速度的类路径扫描。解析器可以将 URL 重写为 包括 JAR 的版本,还可以与没有版本的传入 URL 匹配,例如 fromto。​​/webjars/jquery/jquery.min.js​​​​WebJarsResourceResolver​​​​org.webjars:webjars-locator-core​​​​/webjars/jquery/jquery.min.js​​​​/webjars/jquery/1.2.0/jquery.min.js​

1.12.11. 默认的 Servlet

Spring MVC允许映射theto(从而覆盖映射 容器的默认 Servlet),同时仍允许静态资源请求 由容器的默认 Servlet 处理。它配置具有 URL 映射和最低优先级 相对于其他 URL 映射。​​DispatcherServlet​​​​/​​​​DefaultServletHttpRequestHandler​​​​/**​

此处理程序将所有请求转发到缺省 Servlet。因此,它必须 在所有其他 URL 的顺序中保持最后。那就是 如果您使用,则为案例。或者,如果您设置了 自己的自定义实例,请确保将其属性设置为值 低于的,这是。​​HandlerMappings​​​​<mvc:annotation-driven>​​​​HandlerMapping​​​​order​​​​DefaultServletHttpRequestHandler​​​​Integer.MAX_VALUE​

以下示例演示如何使用默认设置启用该功能:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:default-servlet-handler/>

覆盖 theServlet 映射的警告是,对于 缺省 Servlet 必须按名称而不是按路径检索。尝试自动检测默认的 Servlet 启动时的容器,使用大多数主要 Servlet 的已知名称列表 容器(包括Tomcat,Jetty,GlassFish,JBoss,Resin,WebLogic和WebSphere)。 如果缺省 Servlet 已使用不同的名称进行自定义配置,或者如果 使用不同的 Servlet 容器,其中默认的 Servlet 名称未知, 然后,您必须显式提供默认 Servlet 的名称,如以下示例所示:​​/​​​​RequestDispatcher​​​​DefaultServletHttpRequestHandler​

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable("myCustomDefaultServlet");
}
}

下面的示例演示如何在 XML 中实现相同的配置:

<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>

1.12.12. 路径匹配

网络通量

您可以自定义与路径匹配和 URL 处理相关的选项。 有关各个选项的详细信息,请参阅PathMatchConfigurerjavadoc。

以下示例演示如何在 Java 配置中自定义路径匹配:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
}

private PathPatternParser patternParser() {
// ...
}
}

以下示例演示如何在 XML 配置中自定义路径匹配:

<mvc:annotation-driven>
<mvc:path-matching
path-helper="pathHelper"
path-matcher="pathMatcher"/>
</mvc:annotation-driven>

<bean id="pathHelper" class="org.example.app.MyPathHelper"/>
<bean id="pathMatcher" class="org.example.app.MyPathMatcher"/>

1.12.13. 高级 Java 配置

网络通量

​@EnableWebMvc​​进口,其中:​​DelegatingWebMvcConfiguration​

  • 为 Spring MVC 应用程序提供默认的 Spring 配置
  • 检测并委派给实现以自定义该配置。WebMvcConfigurer

对于高级模式,您可以直接从中删除和扩展而不是实现, 如以下示例所示:​​@EnableWebMvc​​​​DelegatingWebMvcConfiguration​​​​WebMvcConfigurer​

@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration {

// ...
}

您可以保留现有方法,但现在也可以覆盖 Bean 声明 从基类中,您仍然可以在基类上拥有任意数量的其他实现 类路径。​​WebConfig​​​​WebMvcConfigurer​

1.12.14. 高级 XML 配置

MVC 命名空间没有高级模式。如果需要在 上自定义属性 否则无法更改的 bean,您可以使用生命周期 弹簧的钩子,如以下示例所示:​​BeanPostProcessor​​​​ApplicationContext​

@Component
public class MyPostProcessor implements BeanPostProcessor {

public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
// ...
}
}

请注意,您需要在 XML 中显式地对 Bean 进行 clated 或 通过声明让它被检测到。​​MyPostProcessor​​​​<component-scan/>​

1.13. HTTP/2

网络通量

需要 Servlet 4 容器才能支持 HTTP/2,Spring Framework 5 兼容 使用 Servlet API 4。从编程模型的角度来看,没有什么具体的 应用程序需要做。但是,有一些与服务器配置相关的注意事项。 有关更多详细信息,请参阅HTTP/2 wiki 页面。

发表评论

相关文章