基于 Servlet API 并部署到 Servlet 容器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于 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 通过使用指令来防止缓存。0Cache-Control: no-store
  • Anvalue 使用指令将给定的响应缓存几秒钟。n > 0nCache-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 = ;

此基本实现在使用模板之前对其进行编译。生产就绪型 实现还应存储任何重复使用的缓存模板或预编

以上是关于基于 Servlet API 并部署到 Servlet 容器的主要内容,如果未能解决你的问题,请参考以下文章

使用servlet API作为参数

Servlet

JSP/Servlet技术—第七章 Servel基础

关于servlet-api.jar和jsp-api.jar的选择和使用

手动写一个Servlet

JavaWeb核心——Servlet