基于 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 不会生成响应标头。
-1
Cache-Control
- Avalue 通过使用指令来防止缓存。
0
Cache-Control: no-store
- Anvalue 使用指令将给定的响应缓存几秒钟。
n > 0
n
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.宏定义表
宏观 | 整车运输定义 |
| <@spring.message code/> |
| <@spring.messageText code, text/> |
| <@spring.url relativeUrl/> |
| <@spring.formInput path, attributes, fieldType/> |
| <@spring.表单隐藏输入路径、属性/> |
| <@spring.formPassword输入路径、属性/> |
| <@spring.表单文本区域路径、属性/> |
| <@spring.表单单选路径、选项、属性/> |
| <@spring.表单多选路径、选项、属性/> |
| <@spring.表单单选按钮路径、选项分隔符、属性/> |
| <@spring.表单复选框路径、选项、分隔符、属性/> |
| <@spring.表单复选框路径、属性/> |
| <@spring.showErrors 分隔符、classOrStyle/> |
上述任何宏的参数具有一致的含义:
-
path
:要绑定到的字段的名称(即“command.name”) -
options
:输入中可以从中选择的所有可用值 田。映射的键表示从表单中 POST 返回的值 并绑定到命令对象。针对键存储的映射对象是标签 显示在表单上向用户显示,并且可能与相应的值不同 通过表格回发。通常,此类地图由 控制器。您可以使用任何实现,具体取决于所需的行为。 对于严格排序的地图,您可以将 a(例如 a)与 适合并且,适用于应在插入中返回值的任意映射 订购,使用 aor afrom。Map
Map
SortedMap
TreeMap
Comparator
LinkedHashMap
LinkedMap
commons-collections
-
separator
:多个选项作为离散元素可用(单选按钮 或复选框),用于分隔列表中每个字符的字符序列 (如)。<br>
-
attributes
:要包含在其中的任意标签或文本的附加字符串 HTML 标记本身。此字符串由宏逐字回显。例如,在字段中,您可以提供属性(例如“rows=”5“ cols=”60“),或者您 可以传递样式信息,例如“style=”border:1px solid silver“”。textarea
-
classOrStyle
:对于宏,包装每个错误的元素使用的 CSS 类的名称。如果未提供任何信息(或值为 空),错误被包装在标签中。showErrors
span
<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.ScriptEngineFactory
org.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 容器的主要内容,如果未能解决你的问题,请参考以下文章