Use of the Spring JS API is demonstrated in the the Spring MVC + Web Flow version of the Spring Travel reference application. In addition, the JSF components provided as part of the Spring Faces library build on Spring.js.
Spring JS provides a generic
as well as the webapp root directory.
This servlet provides a convenient way to serve Spring.js files to your pages.
To deploy this servlet, declare the following in
<!-- Serves static resource content from .jar files such as spring-js.jar --> <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class> </servlet> <!-- Map all /resources requests to the Resource Servlet for handling --> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping>
Note that starting with version 3.0.4, the Spring Framework includes
a replacement for the
ResourceServlet (see the
Spring Framework documentation).
With the new <mvc:resources> element resource requests (.js, .css) are handled by the
DispatcherSevlet without the need for a separate
Here is the relevant portion of the Spring MVC configuration in
the mvc-booking sample:
<?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 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <mvc:annotation-driven/> <mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/web-resources/" /> ... </beans>
This incoming maps requests for
/resources to resources found under
are bundled. However, you can modify the location attribute in the above configuration in order
to serve resources from any classpath or web application relative location.
Note that the full resource URL depends on how your DispatcherServlet is mapped. In the mvc-booking sample we've chosen to map it with the default servlet mapping '/':
<servlet> <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
That means the full URL to load
DispatcherServlet was instead mapped to
/main/* then the full
URL would be
When using of the default servlet mapping it is also recommended to add this to your Spring MVC configuration, which ensures that any resource requests not handled by your Spring MVC mappings will be delegated back to the Servlet container.
<?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 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> ... <mvc:default-servlet-handler /> </beans>
Spring.js base interface file, and the
Spring-(library implementation).js file for the underlying toolkit.
As an example, the following includes obtain the Dojo implementation of Spring.js using the
When using the widget system of an underlying library, typically you must also include some CSS resources to obtain the desired look and feel.
For the booking-mvc reference application, Dojo's
tundra.css is included:
<link type="text/css" rel="stylesheet" href="<c:url value="/resources/dijit/themes/tundra/tundra.css" />" />
This technique is used to progressively enhance a web page such that the page will still be functional in a less capable browser.
addDecoration method is used to apply decorations.
The following example illustrates enhancing a Spring MVC
<form:input> tag with rich suggestion behavior:
ElementDecoration is used to apply rich widget behavior to an existing DOM node.
This decoration type does not aim to completely hide the underlying toolkit, so the toolkit's native widget type and attributes are used directly.
This approach allows you to use a common decoration model to integrate any widget from the underlying toolkit in a consistent manner.
booking-mvc reference application for more examples of applying decorations to do things from suggestions to client-side validation.
When using the
ElementDecoration to apply widgets that have rich validation behavior, a common need is to prevent the form from being submitted to the server until validation passes.
This can be done with the
This decorates the "Proceed" button with a special onclick event handler that fires the client side validators and does not allow the form to submit until they pass successfully.
AjaxEventDecoration applies a client-side event listener that fires a remote Ajax request to the server. It also auto-registers a callback function to link in the response:
It is also possible to apply more than one decoration to an element. The following example shows a button being decorated with Ajax and validate-all submit suppression:
It is also possible to apply a decoration to multiple elements in a single statement using Dojo's query API. The following example decorates a set of checkbox elements as Dojo Checkbox widgets:
The key interface for integrating various Ajax libraries with the Ajax-aware behavior of Web Flow (such as not redirecting for a
partial page update) is
detect an Ajax request submitted via the Spring JS client-side API and can respond appropriately in the case where a redirect is required. In
component library), a custom
AjaxHandler can be injected into the
In order to handle Ajax requests with Spring MVC controllers, all that is needed is the configuration of the provided Spring MVC extensions in your Spring application context for rendering the partial response (note that these extensions require the use of Tiles for templating):
<bean id="tilesViewResolver" class="org.springframework.js.ajax.AjaxUrlBasedViewResolver"> <property name="viewClass" value="org.springframework.webflow.mvc.view.FlowAjaxTilesView"/> </bean>
This configures the
AjaxUrlBasedViewResolver which in turn interprets Ajax requests and creates
FlowAjaxTilesView objects to handle rendering of the appropriate fragments.
FlowAjaxTilesView is capable of handling the rendering for both Web Flow and pure Spring MVC requests.
The fragments correspond to individual attributes of a Tiles view definition. For example, take the following Tiles view definition:
<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>
An Ajax request could specify the "body", "hotelSearchForm" or "bookingsTable" to be rendered as fragments in the request.
Spring Web Flow handles the optional rendering of fragments directly in the flow definition language through use of the
The benefit of this approach is that the selection of fragments is completely decoupled from client-side code, such that no special parameters need to be passed with the request the way they
currently must be with the pure Spring MVC controller approach.
<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>