20. Spring JavaScript 快速参考
这spring-js-resources
module 是一个旧模块,不再建议使用,但仍作为可选模块提供以实现向后兼容性。
它的最初目标是提供一个客户端编程模型,用于通过行为和 Ajax 远程处理逐步增强网页。
示例存储库中演示了 Spring JS API 的使用。
20.1. 提供 Javascript 资源
Spring Framework 提供了一种提供静态资源的机制。
请参阅 Spring Framework 文档)。
随着新的<mvc:resources>
元素、资源请求 (.js
,.css
等)由DispatcherSevlet
.
以下示例显示了如何在 XML 中配置模块(Java 配置也可用):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:annotation-driven/>
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/web-resources/" />
...
</beans>
这将映射传入请求/resources
到在/META-INF/web-resources
在类路径上。
这就是捆绑 Spring JavaScript 资源的地方。
但是,您可以修改前面配置中的 location 属性,以从相对于类路径或 Web 应用程序的任何位置提供资源。
请注意,完整的资源 URL 取决于您的DispatcherServlet
被映射。
在mvc-booking
sample,我们选择将其映射到默认的 servlet 映射 (),如下所示:/
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
这意味着要加载的完整 URLSpring.js
是/myapp/resources/spring/Spring.js
.
如果您的DispatcherServlet
而是映射到/main/*
,完整 URL 是/myapp/main/resources/spring/Spring.js
.
当您使用默认的 servlet 映射时,您还应该将以下配置添加到您的 Spring MVC 配置中,以确保将 Spring MVC 映射未处理的任何资源请求委托回 servlet 容器:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
...
<mvc:default-servlet-handler />
</beans>
20.2. 在页面中包含 Spring Javascript
Spring JS 的设计使得可以为任何流行的 Javascript 工具包构建其 API 的实现。 Spring.js 的初始实现建立在 Dojo 工具包之上。
在页面中使用 Spring Javascript 需要像往常一样包含底层工具包,Spring.js
base 接口文件,以及Spring-(library implementation).js
文件。
例如,以下Spring.js内容包括使用ResourceServlet
:
<script type="text/javascript" src="<c:url value="/resources/dojo/dojo.js" />"> </script>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring.js" />"> </script>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring-Dojo.js" />"> </script>
使用底层库的小部件系统时,您还必须(通常)包含一些 CSS 资源以获得所需的外观。
对于booking-mvc
参考应用程序,Dojo 的tundra.css
包括:
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/dijit/themes/tundra/tundra.css" />" />
20.3. Spring Javascript 装饰
Spring Javascript 中的一个核心概念是将装饰应用于现有 DOM 节点的概念。
此技术用于逐步增强网页,以便该页面在功能较差的浏览器中仍然正常运行。
这addDecoration
方法用于应用装饰。
以下示例增强了 Spring MVC<form:input>
标签,具有丰富的建议行为:
<form:input id="searchString" path="searchString"/>
<script type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({
elementId: "searchString",
widgetType: "dijit.form.ValidationTextBox",
widgetAttrs: { promptMessage : "Search hotels by name, address, city, or zip." }}));
</script>
这ElementDecoration
调用用于将丰富的小部件行为应用于现有 DOM 节点。
此装饰类型并非旨在完全隐藏底层工具包,因此直接使用工具包的原生小部件类型和属性。
通过这种方法,您可以使用通用装饰模型以一致的方式集成底层工具包中的任何小组件。
请参阅booking-mvc
参考应用程序,了解更多应用装饰来执行从建议到客户端验证的作的示例。
使用ElementDecoration
要应用具有丰富验证行为的小组件,一个常见的需求是阻止表单提交到服务器,直到验证通过。
这可以通过ValidateAllDecoration
如下:
<input type="submit" id="proceed" name="_eventId_proceed" value="Proceed" />
<script type="text/javascript">
Spring.addDecoration(new Spring.ValidateAllDecoration({ elementId:'proceed', event:'onclick' }));
</script>
这用一个特殊的onclick
事件处理程序,该处理程序触发客户端验证器,并且在它们成功通过之前不允许提交表单。
AjaxEventDecoration
应用一个客户端事件侦听器,该侦听器向服务器触发远程 Ajax 请求。
它还会自动注册一个回调函数以链接到响应中。
以下示例使用AjaxEventDecoration
:
<a id="prevLink" href="search?searchString=${criteria.searchString}&page=${criteria.page - 1}">Previous</a>
<script type="text/javascript">
Spring.addDecoration(new Spring.AjaxEventDecoration({
elementId: "prevLink",
event: "onclick",
params: { fragments: "body" }
}));
</script>
前面的列表装饰了onclick
事件,传递一个特殊参数,该参数指定要在响应中重新渲染的片段。
请注意,如果 Javascript 在客户端中不可用,则此链接功能齐全。
(有关如何在服务器上处理此请求的详细信息,请参阅处理 Ajax 请求。
您还可以对一个元素应用多个装饰。 以下示例显示了使用 Ajax 和 validate-all 提交抑制修饰的按钮:
<input type="submit" id="proceed" name="_eventId_proceed" value="Proceed" />
<script type="text/javascript">
Spring.addDecoration(new Spring.ValidateAllDecoration({elementId:'proceed', event:'onclick'}));
Spring.addDecoration(new Spring.AjaxEventDecoration({elementId:'proceed', event:'onclick',formId:'booking', params:{fragments:'messages'}}));
</script>
还可以使用 Dojo 的查询 API 将装饰应用于单个语句中的多个元素。 以下示例将一组复选框元素装饰为 Dojo Checkbox 小部件:
<div id="amenities">
<form:checkbox path="amenities" value="OCEAN_VIEW" label="Ocean View" /></li>
<form:checkbox path="amenities" value="LATE_CHECKOUT" label="Late Checkout" /></li>
<form:checkbox path="amenities" value="MINIBAR" label="Minibar" /></li>
<script type="text/javascript">
dojo.query("#amenities input[type='checkbox']").forEach(function(element) {
Spring.addDecoration(new Spring.ElementDecoration({
elementId: element.id,
widgetType : "dijit.form.CheckBox",
widgetAttrs : { checked : element.checked }
}));
});
</script>
</div>
20.4. 处理 Ajax 请求
Spring Javascript 的客户端 Ajax 响应处理建立在从服务器接收“片段”的概念之上。 这些片段是标准 HTML,旨在替换现有页面的部分内容。 服务器上需要的关键部分是一种确定需要提取完整响应的哪些部分以进行部分渲染的方法。
为了能够呈现完整响应的部分片段,必须使用模板技术来构建完整响应,该技术允许使用组合来构造响应,并单独引用和呈现组合的成员部分。 Spring Javascript 提供了一些简单的 Spring MVC 扩展,它们利用图块来实现这一点。 理论上,相同的技术可以用于任何支持合成的模板系统。
Spring Javascript 的 Ajax 远程处理功能建立在这样一个概念之上,即 Ajax 请求的核心处理代码不应与标准浏览器请求不同。 因此,在代码中不需要直接了解 Ajax 请求的特殊知识,并且您可以对两种样式的请求使用相同的处理程序。
20.4.1. 提供特定于库的AjaxHandler
将各种 Ajax 库与 Web Flow 的 Ajax 感知行为(例如不重定向以进行部分页面更新)集成的关键接口是org.springframework.js.AjaxHandler
.
默认情况下,一个SpringJavascriptAjaxHandler
已配置。它可以检测通过 Spring JS 客户端 API 提交的 Ajax 请求,并在需要重定向时做出适当的响应。
要集成不同的 Ajax 库(无论是纯 JavaScript 库还是更高级别的抽象,例如支持 Ajax 的 JSF 组件库),您可以注入一个自定义AjaxHandler
进入FlowHandlerAdapter
或FlowController
.
20.4.2. 使用 Spring MVC 控制器处理 Ajax 请求
要使用 Spring MVC 控制器处理 Ajax 请求,您需要在 Spring 应用程序上下文中配置提供的 Spring MVC 扩展以呈现部分响应(请注意,这些扩展需要使用磁贴进行模板化),如下所示:
<bean id="tilesViewResolver" class="org.springframework.webflow.mvc.view.AjaxUrlBasedViewResolver">
<property name="viewClass" value="org.springframework.webflow.mvc.view.FlowAjaxTiles3View"/>
</bean>
这配置了AjaxUrlBasedViewResolver
,这反过来又解释 Ajax 请求并创建FlowAjaxTilesView
对象来处理相应片段的渲染。
请注意FlowAjaxTilesView
能够处理 Web Flow 和纯 Spring MVC 请求的渲染。
片段对应于磁贴视图定义的各个属性。
例如,请考虑以下磁贴视图定义:
<definition name="hotels/index" extends="standardLayout">
<put-attribute name="body" value="index.body" />
</definition>
<definition name="index.body" template="/WEB-INF/hotels/index.jsp">
<put-attribute name="hotelSearchForm" value="/WEB-INF/hotels/hotelSearchForm.jsp" />
<put-attribute name="bookingsTable" value="/WEB-INF/hotels/bookingsTable.jsp" />
</definition>
Ajax 请求可以指定body
,hotelSearchForm
或bookingsTable
在请求中呈现为片段。
20.4.3. 使用 Spring MVC 和 Spring Web Flow 处理 Ajax 请求
Spring Web Flow 通过使用render
元素。
这种方法的好处是片段的选择与客户端代码完全解耦,因此不需要像当前使用纯 Spring MVC 控制器方法那样随请求传递特殊参数。
例如,如果您想渲染hotelSearchForm
将前面示例磁贴视图中的片段转换为丰富的 Javascript 弹出窗口,您可以定义以下内容view-state
:
<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
<on-entry>
<render fragments="hotelSearchForm" />
</on-entry>
<transition on="search" to="reviewHotels">
<evaluate expression="searchCriteria.resetPage()"/>
</transition>
</view-state>