20. Spring JavaScript 快速参考
该模块是不再推荐使用的旧模块,但仍作为可选模块提供以实现向后兼容性。
它的最初目标是提供一个客户端编程模型,用于通过行为和 Ajax 远程处理逐步增强 Web 页面。spring-js-resources
示例存储库中演示了 Spring JS API 的使用。
20.1. 提供 Javascript 资源
Spring Framework 提供了一种提供静态资源的机制。
请参阅 Spring Framework 文档)。
使用新元素时,资源请求(、 和其他请求)由 处理。
以下示例显示了如何在 XML 中配置模块(Java 配置也可用):<mvc:resources>
.js
.css
DispatcherSevlet
<?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>
这会将 的传入请求映射到 Classpath 下找到的资源。
这就是捆绑 Spring JavaScript 资源的地方。
但是,您可以修改上述配置中的 location 属性,以便从相对于 Classpath 或 Web 应用程序的任何位置提供资源。/resources
/META-INF/web-resources
请注意,完整的资源 URL 取决于您的映射方式。
在该示例中,我们选择使用默认的 servlet 映射 () 进行映射,如下所示:DispatcherServlet
mvc-booking
/
<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>
这意味着要加载的完整 URL 是 .
如果 映射到 ,则完整 URL 为 。Spring.js
/myapp/resources/spring/Spring.js
DispatcherServlet
/main/*
/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 Toolkit 之上。
在页面中使用 Spring Javascript 需要像往常一样包含底层工具包、基本接口文件和底层工具包的文件。
例如,以下内容包括使用 获取 Spring.js 的 Dojo 实现:Spring.js
Spring-(library implementation).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>
使用基础库的 Widget 系统时,您还必须(通常)包含一些 CSS 资源以获得所需的外观。
对于参考应用程序,包括 Dojo 的:booking-mvc
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 节点的概念。
此技术用于逐步增强 Web 页面,以便该页面在功能较弱的浏览器中仍可正常运行。
该方法用于应用装饰。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>
该调用用于将丰富的小部件行为应用于现有的 DOM 节点。
这种装饰类型并不旨在完全隐藏底层工具包,因此会直接使用工具包的原生小部件类型和属性。
此方法允许您使用通用装饰模型以一致的方式集成底层工具包中的任何小部件。
有关应用装饰执行从建议到客户端验证的更多操作的示例,请参阅参考应用程序。ElementDecoration
booking-mvc
使用 to apply 具有丰富验证行为的小组件时,一个常见的需求是防止将表单提交到服务器,直到验证通过。
这可以通过 来完成,如下所示: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>
这将使用特殊事件处理程序来装饰 “Proceed” 按钮,该处理程序会触发客户端验证器,并且在它们成功通过之前不允许提交表单。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>
前面的清单使用 Ajax 调用修饰了 “Previous Results” 链接的事件,并传递了一个特殊参数,该参数指定要在响应中重新呈现的片段。
请注意,如果 Javascript 在客户端中不可用,则此链接将完全正常运行。
(有关如何在服务器上处理此请求的详细信息,请参阅处理 Ajax 请求。onclick
还可以对一个元素应用多个修饰。 以下示例显示了一个用 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 在单个语句中将装饰应用于多个元素。 以下示例将一组 checkbox 元素装饰为 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 扩展,这些扩展利用 tile 来实现这一点。 理论上,相同的技术可以用于任何支持组合的模板系统。
Spring Javascript 的 Ajax 远程处理功能是建立在 Ajax 请求的核心处理代码不应与标准浏览器请求不同的概念之上的。 因此,不需要直接在代码中了解 Ajax 请求,您可以对两种类型的请求使用相同的处理程序。
20.4.1. 提供特定于 Library 的AjaxHandler
将各种 Ajax 库与 Web Flow 的 Ajax 感知行为(例如,不重定向以进行部分页面更新)的关键接口是 。
默认情况下,配置了 a。它可以检测通过 Spring JS 客户端 API 提交的 Ajax 请求,并且可以在需要重定向时做出适当的响应。
要集成不同的 Ajax 库(无论是纯 JavaScript 库还是更高级别的抽象,例如支持 Ajax 的 JSF 组件库),可以将自定义注入 or .org.springframework.js.AjaxHandler
SpringJavascriptAjaxHandler
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>
这将配置 ,进而解释 Ajax 请求并创建对象以处理相应片段的呈现。
请注意,它能够处理 Web 流和纯 Spring MVC 请求的渲染。
这些片段对应于平铺视图定义的各个属性。
例如,请考虑以下磁贴视图定义:AjaxUrlBasedViewResolver
FlowAjaxTilesView
FlowAjaxTilesView
<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 通过使用元素直接在流定义语言中处理片段的可选渲染。
这种方法的好处是 fragment 的选择与 Client 端代码完全解耦,因此不需要像当前使用纯 Spring MVC 控制器方法那样随请求传递特殊参数。
例如,如果要将上一个示例 tiles 视图中的片段渲染到丰富的 Javascript 弹出窗口中,则可以定义以下内容:render
hotelSearchForm
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>