20. Spring JavaScript 快速参考
这Spring-js-resources模块是一个遗留模块,不再推荐使用,但仍作为可选模块提供以实现向后兼容性。
其最初目标是提供一个客户端编程模型,以逐步增强网页的行为和 Ajax 远程功能。
Spring JS API 的使用方式在示例仓库中得到了演示。
20.1. 服务 JavaScript 资源
Spring 框架提供了一种用于服务静态资源的机制。
参见 Spring Framework 文档)。
与新的<mvc:resources>元素,资源请求 (.js,.css以及其他)由调度员塞夫莱特.
以下示例展示了如何用 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>
这对应了收到的请求/资源资源可于以下/META-INF/web-resources在阶级路径上。
这就是 Spring JavaScript 资源内置地方。
不过,你可以修改前述配置中的位置属性,使其从相对于类路径或网页应用的任何位置提供资源。
请注意,完整的资源网址取决于你的情况调度器服务映射。
在MVC预订样本中,我们选择用默认的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>
也就是说要加载完整的URL。Spring.js是/myapp/resources/spring/Spring.js.
如果你调度器服务而是映射为/主要/*,完整网址为/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 的设计使得其 API 实现可以适用于任何流行的 Javascript 工具包。 Spring.js的初始实现基于Dojo工具包。
在页面中使用 Spring Javascript 需要像正常一样包含底层工具包,Spring.js基础接口文件,以及Spring(库实现).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'stundra.css包含:
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/dijit/themes/tundra/tundra.css" />" />
20.3. 春季 Javascript 装饰
Spring Javascript 的一个核心概念是将装饰应用于现有的 DOM 节点。
该技术用于逐步增强网页功能,使页面在功能较差的浏览器中仍能正常使用。
这附加装饰装饰采用方法。
以下示例增强了春季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 节点应用丰富的控件行为。
这种装饰类型并不旨在完全隐藏底层工具包,因此直接使用工具包的原生小部件类型和属性。
这种方法允许你使用通用的装饰模型,以一致的方式整合底层工具包中的任何控件。
参见Booking-MVC参考应用,提供更多使用装饰来实现从建议到客户验证的示例。
当使用元素装饰对于应用具有丰富验证行为的小部件,常见的需要是防止表单提交服务器,直到验证通过。
这可以通过验证所有装饰如下:
<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(点滴声)事件处理程序,解雇客户端验证者,直到通过前不允许提交表单。
阿贾克斯活动装饰应用客户端事件监听器,向服务器发送远程 Ajax 请求。
它还会自动注册回调函数,将响应链接进来。
以下示例使用阿贾克斯活动装饰:
<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(点滴声)通过 Ajax 调用链接“先前结果”事件,传递一个特殊参数,指定响应中要重新渲染的片段。
请注意,如果客户端无法使用 Javascript,这个链接是完全可用的。
(有关该请求在服务器上的处理详情,请参见处理 Ajax 请求。)
你也可以给一个元素施加多个装饰。 以下示例展示了一个按钮被装饰为 Ajax 和 valid-all submit 抑制:
<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复选框小部件:
<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. 提供专属库阿贾克斯汉德勒
将各种 Ajax 库与 Ajax 感知的 Web Flow 行为(例如不为部分页面更新重定向)集成的关键接口是org.springframework.js.阿贾克斯指挥官.
默认情况下,SpringJavascriptAjaxHandler已配置。它可以检测通过 Spring JS 客户端 API 提交的 Ajax 请求,并在需要重定向时做出适当响应。
要集成不同的 Ajax 库(无论是纯 JavaScript 库还是更高级的抽象,比如支持 Jajax 的 JSF 组件库),你可以注入自定义库阿贾克斯汉德勒进入流量处理适配器或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 请求可以指定身体,hotelSearchForm或预订积分榜在请求中被渲染为片段。
20.4.3. 使用Spring MVC和Spring Web Flow处理Ajax请求
Spring Web Flow 通过使用呈现元素。
这种方法的优点是片段的选择完全与客户端代码解耦,因此请求时无需像目前纯 Spring MVC 控制器方法那样传递特殊参数。
例如,如果你想渲染hotelSearchForm将之前示例tiles视图的片段切换到一个丰富的Javascript弹窗,你可以定义以下内容视图状态:
<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>