Configuring DWR 3.0 with spring using annotations

February 21st, 2009 | Tags: , , ,

I’m a fan of the spring framework and I have recently become a fan of DWR as well. Both of them together are just unstoppable, they take ajax and bean exposure through javascript to a new level. I have written about my experiences integrating the two and about validating forms using ajax. I’d advise you to read at least the integration article before continuing.

Using annotations to configure the spring container is a very useful feature, a majority of developers prefer to use annotations rather than XML files. However, annotation driven configuration of DWR through spring was not possible in older versions of DWR. The new version however, allows such configuration and with ease I might add. You can now use DWR with spring with almost no configuration in your XML files(a little bit of configuration is required but it doesn’t go beyond 10 lines or so). The best part however is that you don’t need to configure a seperate servlet for DWR at all, all calls to dwr can be routed through the spring dispatcher servlet which helps cut down configuration even more.

First the bean which we want to expose :

@Service
@RemoteProxy
public class MyBean {

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

}

The @Service annotation tells spring to initialize this bean as a service. The @RemoteProxy annotation is what tells DWR that we want to expose this bean to the client. Notice the @RemoteMethod annotation, thats what tells DWR to expose this particular method. Only those methods which have this annotation will be exposed by DWR, nothing else. You are free to use as many annotations as you’d like, you can make the bean transactional as well with the @Transactional annotation and still have the bean exposed.

Next comes the web.xml configuration :

<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>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>

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

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

Notice how we do not initialize the org.directwebremoting.spring.DwrSpringServlet or the org.directwebremoting.servlet.DwrServlet. Previous configurations, which required you to list the classes to scan for annotations, are no longer required due to the namespace support provided in the latest versions. Also note how we map all requests to /dwr/* to the spring dispatcher servlet.

Next comes the configuration required by the DispatcherServlet, dwrexample-servlet.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
	    http://www.directwebremoting.org/schema/spring-dwr  http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd">

	<context:annotation-config />
	<tx:annotation-driven />
	<dwr:configuration />
	<dwr:annotation-config />
	<dwr:url-mapping />
	<dwr:controller id="dwrController" debug="true" />
	<context:component-scan base-package="com.codercorp.dwr,com.codercorp.displaytag" />
	<bean
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
		<property name="order" value="1" />
	</bean>
	<bean
		class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
		<property name="order" value="2" />
	</bean>
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

I’m not going to explain the spring related configurationm but just the DWR related config.

<dwr:annotation-config />

asks dwr to scan spring managed classes for annotation related to its configuration, @RemoteProxy and @RemoteMethod. Remember that the element will NOT scan any classes not managed by spring. The element

<dwr:url-mapping />

asks DWR to map the util.js and engine.js files to the dwrController. The element

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

defines the dwrController. The line

<dwr:configuration />

is not required in this particular instance since we aren’t going to configure any beans which aren’t managed by spring but if you need to do so, you must specify such configuration under this element.

Do note the order properties which have been added to the spring config beans, these properties are required for proper functioning of the example. One last thing, the dwr test page which lists out your exposed beans etc no longer works. However, the test pages for the actual beans do work. So if the page http://YOUR-SERVER/YOUR-APP/dwr/ shows blank, don’t panic, just browse over to, http://YOUR-SERVER/YOUR-APP/dwr/test/YOUR-BEAN-NAME and you’ll see the list of exposed methods.

Thats it, you’re good to go. I was stumped by the test page not displaying for a little while so it took me a day to get all this working. Feel free to leave a comment if this has made your life any easier or if you have any questions.

  1. March 11th, 2009 at 20:57
    Quote | #1

    Thanks! I just switched to spring’s annotations and wanted to use DWR in a similar fashion. So that’s exactly what I was looking for.

  2. March 15th, 2009 at 16:41
    Quote | #2

    Notice that if you couple @Service and @RemoteProxy a good alternative would be to use and remove some lines altogether.

  3. Jyrate
    March 19th, 2009 at 11:52
    Quote | #3

    Fan-fairy-tatstic! Just what I was after…

    Now to get a convter going for a custom value object…

  4. kishore
    March 30th, 2009 at 21:26
    Quote | #4

    @RemoteMethod cannot be resolved to be a type is coming when i am trying to use
    @RemoteMethod

  5. John Rock
    April 21st, 2009 at 22:03
    Quote | #5

    Do you know how I can disable the DWR test page? Why would I want users to be able to see that page? I want it gone!

    • Gaurav Arora
      April 21st, 2009 at 23:09
      Quote | #6

      Just do debug=”false”

      • John Rock
        April 22nd, 2009 at 02:35
        Quote | #7

        ha..thanks!

  6. gy
    May 13th, 2009 at 02:05
    Quote | #8

    Hi,

    I have tried the same, but I got the following message at the start-up:
    Error creating bean with name ‘__dwrConfiguration’: Cannot resolve reference to bean ‘__’ while setting bean property ‘creators’ with key []; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘__’: Cannot create inner bean ‘(inner bean)’ of type [org.directwebremoting.spring.BeanCreator] while setting bean property ‘creator’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘(inner bean)’: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:

    Do you have any idea?

    Thanks in advance!

    • dr
      May 21st, 2009 at 15:23
      Quote | #9

      I have the same problem.

    • Igor Romanov
      June 6th, 2009 at 12:55

      I’ve resolved this by supplying name to @RemoteProxy like this:

      @Service
      @RemoteProxy(name=”test-service”)
      public class TestService { … }

      You can check code in DwrAnnotationPostProcessor:

      String javascript = annotation.name();

      String creatorConfigName = “__” + javascript;
      beanCreator.addPropertyValue(“javascript”, javascript);

      Seems like no default value is provided if not specified explicitly.

      • alberlau
        June 12th, 2009 at 18:22

        Hello

        I’m getting: Javascript name MyBeanRemote is used by 2 classes (lt.cu.ebank.office.web.controllers.MyBean and BeanCreator[MyBeanRemote])

        The bean is as follows:

        @Service(“MyBeanController”)
        @RemoteProxy(name=”MyBeanRemote”)
        public class MyBean

        If i remove @Service(“MyBeanController”) and going to url :/dwr/test/MyBeanRemote i’m getting spring exception: No adapter for handler : Does your handler implement a supported interface like Controller?

        If i change @Service to @Controller i’m getting : Javascript name MyBeanRemote is used by 2 classes.

        • Walker
          July 18th, 2009 at 00:52

          This is exactly what I’d like to do (use a @Controller bean instead of a @Service bean). The reason is that I’d like to make an AJAX request that changes an HTTP Session Attribute.

          Currently I get the ‘No bean named ‘XXXX’ is defined’, which I had gotten before with my @Service, but fixed by setting lazy-init=true on my dwrController. This isn’t fixing it when referencing a @Controller bean.

          Any ideas on the best way to do this?

          • Walker
            July 18th, 2009 at 01:33

            Scratch that…I still had the 2.x jar, with 3 it’s working. (now to figure out how I can call the @Controller’s method with a parameter annotated as:

            @RequestMapping
            @RemoteMethod
            public Object controllerMethod (@ModelAttribute(“attribX”) Object attribX)

            and have the attribute injected properly by spring when DWR calls it…(is this even possible?)

          • Gaurav Arora
            August 18th, 2009 at 11:00

            Ofcourse it’s possible, infact it’s the entire point of the integration. :)

          • Anonymous
            December 10th, 2009 at 02:43

            Gaurav Arora :Ofcourse it’s possible, infact it’s the entire point of the integration.

        • zielgruppe
          May 15th, 2010 at 21:17

          Well, has been a while since this post, but there wasn’t really any other source for this. The problem is (I think) that the bean is defined in two different contexts. I moved everything from the global applicationContext.xml to [..]-servlet.xml, and now it works.

      • AshishKumar
        October 12th, 2010 at 14:24

        Can you send/post the complete source code for this “Configuring DWR 3.0 with spring using annotations” ?

      • fangletian
        June 20th, 2013 at 14:33

        3ks so much ! this problem troubled me more than 1 day! but with your advice, i have solved this problem

  7. Gaurav Arora
    June 2nd, 2009 at 19:18

    Sorry for the late reply.

    The error generally appears when you’re mixing DWR+Spring configuration. Also, make sure that the order in which you define your beans is the same as described in the example.

  8. Benny
    July 22nd, 2009 at 05:18

    Thanks, After searching around the net for ages, I finally came upone this.
    Theres nothing to help people with DWR 3 and Spring 3 integration.
    So you set me on the right track.

    At first I was confused what was going on campared to DWR 3 + Spring 2.x integration.
    But its all good now.

    Works for @Controllers
    and as you said watch the order of the configuration tags.

    Thanks

    • Gaurav Arora
      August 18th, 2009 at 11:00

      Thanks for your comment, happy to be of help.

  9. firewolf
    September 11th, 2009 at 16:48

    I think that this line is not working, base-package parameter accept only one package, you can set more context:component for more packages.., for this example it will be work, but package com.codercorp.displaytag will not be included in scan, only first one! maybe it helps someone!

  10. Shiby
    October 15th, 2009 at 15:46

    Hi,

    I was trying out the integration of DWR 3.0 and Spring 2.5.5. I have some doubts.
    1. Will the annotations alone enough without use of tags for service beans? If so, what all configurations are to be done.
    2. dwr:component-scan is not at all working for me.

    can you please help me?

    Regards,
    Shiby

  11. Sean Parsons
    October 28th, 2009 at 05:38

    Let me go ahead and give a warning for everyone, because I fought this for 10 hours, and wanted to shoot myself and DWR.

    In Spring MVC, if you write your own WebBindingInitializer (which is the same thing as @InitBinder, and is used by ALL your controllers) and intialize it via:

    (google it if you are lost)

    This will NOT work with DWR. the DwrController ends up with ONLY this handler, and none of the other handlers exist in Spring, causing nothing to work. It blows whether annotated, or the 2.x way.

  12. eros
    November 30th, 2009 at 14:40

    just integrate the DWR to SpringMVC-SWF but it turns to extremely slow page loads..

    any hints guys?

    • eros
      November 30th, 2009 at 14:41

      i also changed the debug value.

      but still extremely slow performance.

  13. Cronida
    December 10th, 2009 at 19:52

    Hi! Thanks for the post…
    What version of DWR are you using? I’m trying to use 3.0.0.RC1 and 3.0.M1, but i get errors loading the XML definition:

    cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ‘dwr:configuration’.

    Any idea?

    Thanks!
    Cronida

    • Cronida
      December 10th, 2009 at 20:20

      Well… My problem was I could not find the xsd. Now I get it locally.
      I am having the following error:

      org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [annotation-config]

      Again… Any idea? :)

      Cronida

      • karthik
        September 5th, 2010 at 20:13

        Make sure you have the right version of DWR jar on server class path.

        org.directwebremoting
        dwr
        3.0.M1

      • Anonymous
        October 8th, 2010 at 00:09

        I’m having the same issue… could you tell me how did you solve it! Thanks.

        • Francisco Aranda
          October 8th, 2010 at 00:10

          I’m having the same issue… could you tell me how did you solve it! It’s not DWR version.

          • mawek
            November 18th, 2010 at 05:08

            Any ideas? I’m facing that issue too. Can’t figure it out.

          • Teemu
            June 1st, 2011 at 18:04

            I had the same problem, was missing servlet mapping in web.xml:

            dispatcher
            /dwr/*

  14. Steve
    December 28th, 2009 at 00:26

    I try to do uptade Dwr 2.0 to 3.0 and i have this error :

    org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/spoople-servlet.xml]; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.directwebremoting.spring.DwrNamespaceHandler]: Is it an abstract class?; nested exception is java.lang.InstantiationException

    can yo help me?

    • karthik
      September 5th, 2010 at 20:09

      Make sure you only have one version of DWR jar. Which should be

      org.directwebremoting
      dwr
      3.0.M1

  15. Vishal Bhanderi
    January 3rd, 2010 at 21:45

    This tutorial is great!

    I popped into one error:
    javax.servlet.ServletException: No adapter for handler [org.directwebremoting.spring.DwrController@….

    But that was simply fixed by adding:

    into the spring beans xml file

    • Anjan
      February 12th, 2010 at 03:22

      What did u add to fix this issue?

    • Solid
      March 21st, 2010 at 20:27

      Vishal, your post got cut off!!!! what did you do to fix this error?

      • Asad
        August 12th, 2011 at 19:57

        This is my configuration below. After struggling two days I managed it to work.
        it seems like add “SimpleControllerHandlerAdapter” has fixed it. enjoy.

        “”

        • Asad
          August 12th, 2011 at 19:58

          This is my configuration below. After struggling two days I managed it to work.
          it seems like add “SimpleControllerHandlerAdapter” has fixed it. enjoy.

          “”

          • Asad
            August 12th, 2011 at 19:59

            mypost is cutting automatically.add this bean “”

  16. January 18th, 2010 at 06:06

    Hi,

    I feel this integration won’t work,
    if someone knows how to integrate using annotations mentioned above please provide a sample working project

    thanks

  17. Anjan
    February 12th, 2010 at 03:12

    Can you please give an example on the JSP how do we invoke DWR method exposed using @RemoteProxy. I know how to do it in DWR and spring 2.5 but not for DWR 3.0 and Spring 3.0 together when used. The article you have written is too good, but I don’t know abt the JSP how I should invoke

  18. Aries Satriana
    February 15th, 2010 at 16:53

    I’ve just migrating from DWR 2 into DWR 3.0.
    I follow as you describe and viola when I kick url <http://localhost://test/ItemController

    I’ve got message on page ” Error: java.lang.SecurityException: No class by name: ItemController”.

    Any ideas? since I already map using @Controller in my bean.

    Rgds,
    Aries

  19. Aries Satriana
    February 15th, 2010 at 17:05

    I add configuration on applicationContext.xml as describe below :

    dwrController

    Than i kick url : http://localhost:8084/SpringMVCItemCategoryWiringAnnotationDWR/dwr
    Viola now I have list about classes known to DWR. But none class controller on there even I already mark with @RemoteProxy and @RemoteMethod.
    Error message as describe on my previous comments.
    Any ideas?

    Rgds,
    Aries

  20. Atul
    March 17th, 2010 at 12:13

    Hi,

    can anybody tell me how can I integrate ExtJs with DWR and Spring.
    I already done it with DWR 2 and Spring 2.5. But I am looking it with DWR 3 and Spring MVC. If you guys have any idea please share it.

  21. Atul
    March 17th, 2010 at 12:16

    Hi,

    I integrate DWR 3.0 with Spring 2.5 and its working fine for me. Now I am looking for ExtJs with DWR and Spring. Can anybody tell me how can I do that. I already done a mock example but I am not pretty sure about it. If any one have any idea please share it.

  22. Enez
    March 26th, 2010 at 20:58

    I want to use Spring 3 and dwr 3 and their annotated capabilities. I set all spring properties (web.xml , servlet) , annotate controllers.

    When I want to use DWR with annotations integrated in spring i get :

    java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Duplicate name found. See logs for details.
    at org.directwebremoting.spring.SpringConfigurator.configure(SpringConfigurator.java:143)
    …………….
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘DwrAnnotationURLMapper’: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘__dwrController’: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Duplicate name found. See logs for details.

    I can’t find solution.

  23. Sam Browne
    April 1st, 2010 at 03:09

    Excellent guide to get me up and running,

    1 comment though was that the section “Next comes the configuration required by the DispatcherServlet, :” states to update dwrexample-servlet.xml, I found that I needed to put these updates in the /WEB-INF/applicationContext.xml file referenced from the web.xml.

  24. Enrico Pizzi
    July 23rd, 2010 at 16:32

    I’m trying to make this work with Spring 3.0.3′s mvc:annotation-driven approach, but have failed so far with exception:

    javax.servlet.ServletException: No adapter for handler [org.directwebremoting.spring.DwrController@36d2b3]: Does your handler implement a supported interface like Controller?

    The problem is that with mvc:annotation-driven directive, only classes annotated with @Controller stereotype can act as controllers in Spring, but it seems that DwrController is not annotated with @Controller.

    Any workaround for this? (aside from modifying the dwr framework to add @Controller to class DwrController)

    Thanks,

    Enrico

  25. karthik
    September 5th, 2010 at 20:55

    If any one is using Spring ROO, use the below URL to access your test dwr page

    ( missing /dwr )

    http://YOUR-SERVER/YOUR-APP/test/YOUR-BEAN-NAME

  26. luca
    September 16th, 2010 at 20:58

    I have used the same approach, but i got a Pojo Object. I used the annotation, but i cannot access to field. Any suggestion?
    @DataTransferObject
    public class Person(){
    @remoteProperty
    idPerson;

    getIdPerson(){
    return idPerson;
    }

    }
    The pojo i configured with correct annotation

    person.idPerson

  27. September 17th, 2010 at 11:52

    Hey It seems this ain’t working for 3.0rc1 , has anyone got through using this version instead of 3.0m1
    Regards
    Mudassar

  28. AshishKumar
    October 12th, 2010 at 10:47

    Please send me this complete code/working code links, I am unable to get the jsp/application-context xml files.

  29. Jun Ouyang
    June 18th, 2011 at 06:00

    I will kiss you, this works perfectly!

  30. indrajit
    August 6th, 2011 at 14:23

    i got the error using spring 3.0 with DWR 3.0

    Configuration problem: Configuration problem: Id is required for element ‘annotation-config’ when used as a top-level tag

  31. indrajit
    August 6th, 2011 at 14:24

    i got the error using spring 3.0 with DWR 3.0

    Configuration problem: Configuration problem: Id is required for element ‘annotation-config’ when used as a top-level tag

    <!– This is required if you want to configure any beans not managed by
    Spring. Leaving it enabled doesn't do any negative effects. Here's a
    sample config:

    –>

  32. shahsubhash
    August 7th, 2011 at 01:49

    I am trying to integrate spring 3.0.5 with DWR 3. After following the steps, I got the error
    java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Duplicate name found. See logs for details.
    at org.directwebremoting.spring.SpringConfigurator.configure(SpringConfigurator.java:143)

    I am unable to find the solution. I tried many of alternative approaches but didn’t find anything which may work. Does anybody help me finding the solution?

  33. Asad
    August 12th, 2011 at 20:01

    I dont know the reason why my post is reducing automatically when i post something. below is the configuration that worked for me. adding org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter solved it for me.

  34. September 5th, 2011 at 22:06

    Hi
    I’m going to spare more time learning about this post

  35. jignesh patel
    October 25th, 2011 at 11:26

    hi i use spring 3.0 in my project. & i want to use dwr on it. when i declare @remoteproxy at that time error eccurs to start server.

  36. jignesh patel
    October 25th, 2011 at 11:29

    my dwr configation is like this…..

    dwrController

    now if i declare my service @Remoteproxy at that time error comes. if anything missing then tell me.,

  37. Satya
    May 25th, 2012 at 13:14

    Iam getting below error when calling the DWR Method (Integrating Spring3 and DWR3M)
    Any help to resolve this issue. Below is the server log. In the front-end displaying an alert message like “Error”…:

    2012-05-25 13:05:08,828 DEBUG [org.directwebremoting.log.scripts] dwr.engine.remote.handleNewScriptSession(“152055D75491C568FA073713672E7C66″);
    2012-05-25 13:05:08,828 DEBUG [org.directwebremoting.log.scripts] dwr.engine.remote.handleCallback(“0″,”0″,null);
    2012-05-25 13:05:08,828 DEBUG [org.springframework.web.servlet.DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name ‘springservletname’: assuming HandlerAdapter completed request handling
    2012-05-25 13:05:08,828 DEBUG [org.springframework.web.servlet.DispatcherServlet] Successfully completed request
    2012-05-25 13:05:10,350 DEBUG [org.springframework.web.servlet.DispatcherServlet] DispatcherServlet with name ‘springservletname’ processing POST request for [/springservletname/dwr/call/plaincall/BugType.getBugStatus.dwr]
    2012-05-25 13:05:10,366 DEBUG [org.directwebremoting.spring.DwrHandlerMapping] Matching patterns for request [/call/plaincall/BugType.getBugStatus.dwr] are [/call/**]
    2012-05-25 13:05:10,366 DEBUG [org.directwebremoting.spring.DwrHandlerMapping] URI Template variables for request [/call/plaincall/BugType.getBugStatus.dwr] are {}
    2012-05-25 13:05:10,366 DEBUG [org.directwebremoting.spring.DwrHandlerMapping] Mapping [/call/plaincall/BugType.getBugStatus.dwr] to HandlerExecutionChain with handler [org.directwebremoting.spring.DwrController@20d673] and 1 interceptor
    2012-05-25 13:05:10,366 DEBUG [org.directwebremoting.log.scripts] dwr.engine.remote.handleException(“1″,”0″,{javaClassName:”java.lang.Throwable”,message:”Error”});
    2012-05-25 13:05:10,366 DEBUG [org.springframework.web.servlet.DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name ‘springservletname’: assuming HandlerAdapter completed request handling
    2012-05-25 13:05:10,366 DEBUG [org.springframework.web.servlet.DispatcherServlet] Successfully completed request

    • Gaurav Arora
      May 28th, 2012 at 10:54

      Satya,
      From what I can tell by a cursory look, it seems your spring configuration is not correct because it doesn’t seem to be returning a proper model and view.

      Hope this helps.

  38. Prakash S
    August 6th, 2012 at 10:48

    @RemoteProxy
    public class MyBean {

    @RemoteMethod
    public Address getAddress(){
    return new Address();
    }

    public MyBean() { }

    }

    Results in
    java.lang.IllegalArgumentException: Duplicate name found.

1 trackbacks

Comments are closed.