Dwr + Spring integration example

February 7th, 2009 | Tags: , , ,

I like DWR, it’s a very strong framework for enriching your simple web application with ajax. It’s particularly useful for java developers because no one likes to write javascript to make XMLHttpRequest’s to call the server, parse the response and then set stuff in your jsp so that the response is displayed in a proper manner. You can effectively expose your entire class simply by defining it’s methods in your dwr.xml and then writing converter’s for your objects. The util.js that comes with dwr is very useful too even if you aren’t using dwr, it provides a lot of helpful methods to do stuff in javascript.

The debug page is probably what I loved the most about dwr. It lists out what classes have been exposed including their methods in a very simple manner. You can immediately test if you have configured dwr and if it’s working properly. You can also test out your exposed methods, with and without parameters, and see their responses. It’s lovely and I wish more applications would do this.

Running DWR with spring however is a totally different matter. There is so little material that is available on the internet that it boggles my mind. There is no clear cut example of how to integrate the two. There are some useful tutorials but they don’t list out enough configuration for them to be useful enough and unless you’re very good with the spring framework and know how it works inside out, you might be stuck for a long long time. The fact that there are threee versions of dwr, all with very different integration techniques, makes it even more difficult.

I decided to integrate spring 2.5.5 and dwr 2.0.5. My first mistake was to use DwrServlet instead of DwrSpringServlet. DwrServlet should only be used when you want DWR to manage and expose your beans. If you want DWR to expose your Spring-managed beans then you must use DwrSpringServlet.

First some spring configuration in your web.xml :

<servlet>
	<servlet-name>dwrexample</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

<context-param>
	<param-name>log4jConfigLocation</param-name>
	<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<servlet-mapping>
	<servlet-name>dwrexample</servlet-name>
	<url-pattern>*.html</url-pattern>
</servlet-mapping>

<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Then some dwr configuration in your web.xml:

<servlet>
	<servlet-name>dwr</servlet-name>
	<servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
	<init-param>
		<param-name>debug</param-name>
		<param-value>true</param-value>
	</init-param>
</servlet>

<servlet-mapping>
	<servlet-name>dwr</servlet-name>
	<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

Thats it, your basic configuration is done. You can now run your webapp and see if everything works.

DWR 2.0 has spring namespace support so you don’t need to write a dwr.xml anymore. You can simply configure dwr exposure of your beans when you configure them in spring. A little bit of configuration is required before you do that though.

In your application-servlet.xml add the following :

<dwr:configuration />
<dwr:controller id="dwrController" debug="true" />

Don’t forget to add the namespace first :

xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"

Now, add the following configuration to whatever bean you want to expose. Here I expose my dao and it’s methods getAllCountries() and getStatesForCountry() :

<bean id="generalDao" class="com.codercorp.dwr.JdbcGeneralDao">
	<property name="dataSource" ref="dataSource" />
	<dwr:remote javascript="generalDao">
		<dwr:include method="getAllCountries" />
		<dwr:include method="getStatesForCountry" />
		<dwr:convert type="bean" class="com.codercorp.dwr.Country">
			<dwr:include method="id" />
			<dwr:include method="name" />
		</dwr:convert>
		<dwr:convert type="bean" class="com.codercorp.dwr.State">
			<dwr:include method="id" />
			<dwr:include method="name" />
			<dwr:include method="country" />
		</dwr:convert>
	</dwr:remote>
</bean>

The converter tells DWR what properties of my beans should be used to convert the data it gets into that particular bean. Primitive data types are converted automatically but if you have a POJO that you want converted then you must state it’s properties explicitly.

That’s bascically it. Navigate to your the /dwr directory in your web application. The exposed pojo should show there like this (click on image to see it clearly)
dwr-1

The methods of generalDao are listed here along with how you should use it’s corresponding js file in your view (click on image to see it clearly)
dwr-2

You can click on the execute button to see what your method returns, great for seeing a list of your exposed methods as well as testing them out.

I hope this tutorial of sorts makes someone life’s easier, it took me a couple of days to figure out how to get all of this to work. :)

Share and Enjoy:
  • del.icio.us
  • Google Bookmarks
  • DZone
  • Reddit
  • Digg
  • Facebook
  • Netvibes
  • StumbleUpon
  • Technorati
  • LinkedIn
  • MySpace
  • Print
  • Slashdot
  • Share/Bookmark

No related posts.

  1. February 19th, 2009 at 07:05
    Reply | Quote | #1

    Hi, thanks for this tutorial. I’m using the old configuration where you have to include a dwr.xml. But in here, you have the namespace. Nice post. I have a question, what if your generalDao returns a List? How can you iterate that in your script in dwr?

    • February 19th, 2009 at 07:06
      Reply | Quote | #2

      List

    • Gaurav Arora
      February 19th, 2009 at 11:07
      Reply | Quote | #3

      @Benedict :
      The advantages of using the namespace are numerous, if nothing else it simplifies the configuration to a great deal. I haven’t yet tried iterating over the list but I will do so and drop you a mail with the solution.

      Gaurav

    • Gaurav Arora
      February 19th, 2009 at 14:41
      Reply | Quote | #4

      @Benedict:
      I couldn’t really find anything DWR specific but when my method returned a list, it was fed into my callback function as an array. I am assuming DWR converts Lists and other collection(s) types to arrays and puts them in the callback function. Extremely convenient I must say.

      The code:

      var callback = function(data) {
      iHtml = "";
      for (key in data) {
      iHtml = iHtml + key + " ";
      }
      dwr.util.byId('a').innerHTML = iHtml;
      }
      function callMe() {
      generalDao.getStuff(callback);
      }

      where a is a div in my page. This callback function is the one I experimented with, the data passes to it was from a java method :

      public List getStuff() {
      List
      list = new ArrayList();
      for (int i = 0; i < 100; i++) {
      list.add(i);
      }
      return list;
      }

  2. MemDude
    February 19th, 2009 at 09:20
    Reply | Quote | #5

    I’m using DWR with Spring on a current project. And here’s the problem I have with DWR: It makes it way too easy to violate the MVC design pattern. For example, if you have an “Employee” object on your Java server then it will eventually be exposed on the Javascript side through DWR ,and viola! Your domain object now exists in the browser when really it belongs only on the server.

    • Gaurav Arora
      February 19th, 2009 at 11:16
      Reply | Quote | #6

      @MemDude:
      I don’t think the existence of an object in the view violates the pattern at all. Even if you don’t use DWR, you still pass your business objects to your view to display their attributes, by your logic, that is a violation of the pattern as well. Secondly, remember we don’t expose the objects per se in the javascript, what we expose are methods to perform actions on them which once again, is not a violation.

      Gaurav

    • Asad
      December 21st, 2009 at 18:50
      Reply | Quote | #7

      @MemDude..i c what u are saying .. to cater this problem i used VO(value object) instead of business object on client side. i would extract the data i need on client side, put it in a pojo or bean or vo and then send it to client.
      i hope you understand me….

  3. Avtar
    March 9th, 2009 at 01:33
    Reply | Quote | #8

    ..i’ve been trying to configure dwr with spring..this is the best tutorial i have come across..just one request how would you include your methods in a jsp page..

    Avtar

  4. kishore
    March 30th, 2009 at 21:46
    Reply | Quote | #9

    i am struck up with the error like @RemoteProxy cannot be resolved to be atype

    • Gaurav Arora
      March 30th, 2009 at 22:55

      What version of DWR are you using? Make sure it’s 3.0RC1 or later.

  5. Shailesh
    April 23rd, 2009 at 23:15

    When you’re using DWR with Spring, I don’t believe you need to define any servlet and its mapping in your web.xml. Just use the dwr:controller bean definition in your applicationContext and then use the SimpleUrlMapping to map all the required mappings to dwrController:
    /dwr/**=dwrController
    /engine.js=dwrController
    /util.js=dwrController
    /call/**=dwrController
    /interface/**=dwrController

    I was able to get it to work with no DWR reference in web.xml.

    Versions used: DWR-2.0.3, spring-2.5.6

    • Gaurav Arora
      April 24th, 2009 at 01:02

      Yes, thats another way of doing it. But notice the difference in lines of code in your example and in mine.

      • Shailesh
        April 24th, 2009 at 03:03

        I don’t know about you, but I get paid by lines of code :)

        Kidding aside, I think there is some value of not having multiple servlets – especially when you are using Spring. By using the way I mentioned, all (or most) of your URL mappings are contained within the application context configuration files. In addition, you can probably configure it with other things while its in there. Thanks for the blog, it was good to have it available as reference.

  6. jiojoijiojoki
    June 9th, 2009 at 17:53

    ]]]\]’[pp

  7. zoom
    July 8th, 2009 at 16:58

    Just a quick question. I am a little confused! If I use a dwr.xml do I still need to use the tag in the bean I wish to expose?

  8. zoom
    July 8th, 2009 at 17:00

    I meant the dwr:remote tag

    • eros
      November 25th, 2009 at 12:52

      hi zoom,
      don’t need to use dwr:remote tag

      eros

  9. charls
    August 18th, 2009 at 22:09

    Can u help me to install that framework, where is located the WEB-INF/lib directory???????????????????

  10. sweta
    August 26th, 2009 at 12:53

    I have followed the same steps as mentioned in this example but when i include
    org.directwebremoting.spring.DwrSpringServlet in web.xml i get the error:

    javax.servlet.ServletException: No DWR configuration was found in your application context, make sure to define one
    root cause
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘__dwrConfiguration’ is defined

    But when i use
    org.directwebremoting.servlet.DwrServlet in web.xml and use dwr.xml it works fine.

    Could you tell me why i’m getting this error.
    I am using spring 2.5.5 and dwr 2.0.5.

    • ShiningNorthStar
      November 13th, 2009 at 15:58

      I had the same problem and it occurred because I was listing the dwr configuration in my dispatcher servlet config file rather than in my spring web-app config file.

      HTH

  11. manoj
    September 21st, 2009 at 18:09

    Can you publish the source code to this example/tutorial?

    Manoj

  12. anthrex
    September 30th, 2009 at 09:54

    thanks man, you really made someone’s life easy.

  13. Vineet
    November 18th, 2009 at 12:59

    Tutorial is very helpful, but I am still not able to run it. :(
    A sample project wil be very much helpful. will clear all the doubts from configuration to usage.

    Can you please publish a sample project?

  14. eros
    November 25th, 2009 at 12:02

    hi peepz,

    I just like to confirm if you don’t need to add the dwr schema location in application context?

    xsi:schemaLocation=”beans… aop… tx… http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd

    if yes, may i know your settings?

  15. eros
    November 25th, 2009 at 12:51

    zoom :I meant the dwr:remote tag

    don’t need

    eros

  16. S Ravi shankar
    December 3rd, 2009 at 02:26

    Hey,
    Thanks a lot man. this article is really helped me alot.

  17. Asad
    December 21st, 2009 at 18:42

    @MemDude..i c what u are saying .. to cater this problem i used VO(value object) instead of business object on client side. i would extract the data i need on client side, put it in a pojo or bean or vo and then send it to client.
    i hope you understand me

  18. January 21st, 2010 at 23:16

    Hi Everyone,
    I am new in software development,i would like if anyone can send a simple application using DWR+Spring on my emailId,please its urgent ,i am very much tensed.

  19. algol1983
    March 2nd, 2010 at 23:03

    Thank you)

  20. 2 trackbacks
TOP