Ok, so you want to create a more intuitive and responsive web application?
And you’ve decided to give AJAX, HttpXmlRequest, DWR or any other buzzword of the last few months, a try?
Although DWR comes with some build-in Spring support, there is no out-of-the-box seamless integration with your Spring web application. For instance, it requires a separate servlet to be defined in your web.xml and has no means of accessing beans from your web application context.
Let’s get started
Ok, first of all let’s configure the
DwrServlet as a Spring MVC controller instead of a separate servlet. Luckily for us, Spring provides a controller which does just that, the ServletWrappingController. Add the following code to your dispatcher servlet application context in order to enable DWR as a standard controller.
<bean id="dwrController" class= "org.springframework.web.servlet.mvc.ServletWrappingController"> <property name="servletClass"> <value>uk.ltd.getahead.dwr.DWRServlet</value> </property> <property name="initParameters"> <props> <prop key="debug">true</prop> </props> </property> </bean>
debug init parameter, which is recommended during development, as it provides useful bean listings. More importantly, note the way to specify init parameters to configure DWR.
Add an entry to your url mapping which maps all requests for a certain context path to this controller. Note that the example below is just one example of how to map all request for an entire path. Note that the mapping of the
dwrController should be the last mapping as it catches all requests.
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/**/*.html">defaultController</prop> <prop key="/**/*">dwrController</prop> </props> </property> </bean>
Also make sure to map requests for files with all extensions (and without extensions) to the Spring dispatcher servlet in your
web.xml. So, instead of mapping just JSP or HTML extensions, make sure to map request for all file extensions like in the example below. The example assumes a Spring
DispatcherServlet to be defined, named main.
<servlet-mapping> <servlet-name>main</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
The DWR servlet assumes a configuration file:
/WEB-INF/dwr.xml, although this is configurable as an init parameter. Below is a sample configuration file, which assumes a bean with id
productManager in your application context.
First of all, note that currently DWR includes a Spring creator by default. This creator allows you to expose the
productManager which is defined in your web application context. This can either be used to create a new application context, or to lookup an existing servlet application context or global web application context. This example assumes an existing application context to be available.
Last, you define a <create> entry for each bean you want to expose through DWR. In this example we expose a bean with id
Access your bean
Now that we’re all set up, let’s access our exposed product manager. Assume the product manager has a method
getAllProducts() which returns a
Where ‘dwrPath‘ is the path under which you mapped the
dwrController. Now, the only thing you have to do is call the method on the product manager. Assume we want have a button to retrieve the information and a span to display the product information in an unordered list:
Note the nested properties
price.value. They are resolved correctly only when the
Price class are under the path matched by the bean converter (i.e.
your.package. in this example). Posting nested properties back to the server is not yet supported.
DWR has some build in debugging support. As we set the debug init parameter to true, this debugging support is enabled. Point your browser to the path /dwrPath, where ‘dwrPath‘ is the path under which you mapped the
dwrController. You will now get a listing of all beans that are exposed through DWR. By clicking one of them, you get a listing of all methods that are exposed. You can use this page to get examples of how to call the method (in the source).
DWR has also some build in utility functions and means to perform error handling. More information on this can be found here. Also note that DWR claims to fallback to iframes for invoking methods on the server on platforms that do not support the
HttpXmlRequest method, which should ensure high browser compatibility.
I hope this small tutorial has given you some inside into how to use DWR in conjunction with Spring and help you to easily build web application using the AJAX technology. I’m currently looking into real-time, server-side form validation using this technology. Check back on this blog in order to stay up to date on the progress.