atom feed13 messages in net.java.dev.dwr.usersRe: [dwr-user] DWR 3 annotations with...
FromSent OnAttachments
John GordonJan 7, 2009 5:22 pm 
Jose NohedaJan 8, 2009 1:24 am 
John GordonJan 8, 2009 11:18 am 
Jose NohedaJan 9, 2009 1:22 am 
John GordonJan 9, 2009 9:17 am 
Kudinov, AlekseyJan 9, 2009 11:05 am 
Jose NohedaJan 9, 2009 12:02 pm 
John GordonJan 9, 2009 2:49 pm 
Jose NohedaJan 9, 2009 3:46 pm.java, .xml, .xml
John GordonJan 9, 2009 8:07 pm 
Jose NohedaJan 10, 2009 2:19 am 
Kudinov, AlekseyJan 20, 2009 6:45 am 
Joe WalkerJan 20, 2009 8:38 am 
Subject:Re: [dwr-user] DWR 3 annotations with Spring Injection
From:John Gordon (john@gmail.com)
Date:Jan 9, 2009 8:07:23 pm
List:net.java.dev.dwr.users

Eureka, it works!

The only last remaining item is that I haven't figured out how to get the debug index page to show, the page where dwr lists out all the known exposed classes. I can, however, access my exposed class' test page via [my-web-app]/dwr/test/[exposed-bean-name] .

It looks like the big change I needed to make was to change how I wrote the annotations on my exposed beans. I'd been trying to set up annotations per this discussion: http://blog.gtuhl.com/2007/03/15/dwr-annotations-spring/. These instructions work fine if you're instantiating the DwrSpringServlet in web.xml, but not if you're configuring dwr using <dwr:controller /> . Consequently, I changed:

@RemoteProxy( creator = SpringCreator.class, creatorParams = @Param(name = "beanName", value = "RemoteTest"), name = "RemoteTest") @Component public class RemoteTestImpl implements RemoteTest {

...

to just this:

@RemoteProxy(name = "RemoteTest") @Component public class RemoteTestImpl implements RemoteTest {

...

and also made the changes in the spring config files, per your direction. It's nice to see the annotations being simplified. I was thinking of writing about it, is there anything you think I should point out specifically?

John

2009/1/9 Jose Noheda <jose@gmail.com>

On Fri, Jan 9, 2009 at 11:49 PM, John Gordon <john@gmail.com>wrote:

Jose,

I tried the changes you indicated below but still didn't get any luck with it. The only way I've been getting things to work is by using the DwrSpringServlet. I went ahead and put together the project I'm working on for you to take a look at. Again, the goal is to have DWR work without there needing to be a servlet defined in web.xml. The only thing to add, is that this is a proof of concept app. For my real work I'll need to have an applicationContext.xml file and Spring's annotations. Download it here (5MB):

http://gordonjl.com/files/dwr_test.zip

1) unzip 2) run ant

It will create a war file in the artifacts directory. I'm using Tomcat as my server, but it should probably work anywhere, there's nothing fancy about it.

If you get this sucker to work without having to declare the DwrSpringServlet, you will have attained the ranks of godhood in my humble mind.

Be Well!

On Fri, Jan 9, 2009 at 3:03 PM, Jose Noheda <jose@gmail.com>wrote:

On Fri, Jan 9, 2009 at 6:17 PM, John Gordon <john@gmail.com>wrote:

Hi, Jose,

Thanks for the responses (as usual :-) ).

You're welcome

As it turns out, the test pages _are_ working. I was tripped up by not putting quotation marks in the test text fields. Once I did that, it worked fine. That just leaves the last issue with not having to create a Servlet especially for DWR, and just using Spring's Dispatcher servlet. I've tried to omit the SpringDispatcherServlet from my web.xml and using the dwr tags in applicationContext.xml and dispatcher-servlet.xml, but dwr then doesn't load my dwr-annotated classes. On the positive side, it looks like the <dwr:url-mapping /> does work; I'm able to load util.js and engine.js, but my RemoteTest class' javascript still doesn't load. Any idea why dwr isn't finding the annotated class when trying the setup you described below, but it can when I use the DwrSpringServlet in web.xml?

Here are all my config files. Would you help me figure out what config tags go in which files?

web.xml:

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

Remove the lines above

<listener>

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

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

That's ok.

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

Remove the lines above.

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

Change the lines above to:

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

applicationContext.xml:

Leave applicationContext.xml empty. In fact if you don't have any more beans than the DWR test bean remove the listener from web.xml and applicationContext.xml altogether.

<context:component-scan base-package="com.gordonjl"/> <context:annotation-config />

<dwr:configuration/> <dwr:annotation-config/>

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

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

dispatcher-servlet.xml:

[nothing!]

Add this lines to dispatcher-servlet.xml (keep this order):

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="1" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" p:order="2" /> <dwr:configuration /> <dwr:controller id="dwrController" debug="true" /> <dwr:url-mapping /> <dwr:annotation-scan base-package="com.gordonjl" />

Regards

On Fri, Jan 9, 2009 at 4:23 AM, Jose Noheda <jose@gmail.com>wrote:

On Thu, Jan 8, 2009 at 8:18 PM, John Gordon <john@gmail.com>wrote:

Jose,

Great news! Thanks to your last post, I was able to put all the DWR and Spring annotations into the java files, leaving my spring config files pretty much empty (except for calls to load annotations for the systems). There are two remaining issues I'm finding with the DWR integration I was hoping you could lend some help with:

Outstanding Items:

--DWR works in script, but the test page doesn't do anything when my method is invoked (a simple echo method that returns a string).

Right now I'm not sure if DWR works for you or not

--It sounds like you don't need to create a specific DWR servlet, but when I don't, anything under dwr doesn't work.

No if you're using DispatcherServlet

My Testing reveals the following:

If I remove the servlet for DwrSpringServlet and create a mapping in web.xml like this:

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

You don't need a specific dwr mapping for dispatcher.

DWR is loaded correctly,but I get the following error when hitting any of the [myApp]/dwr links:

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

Weird. It seems it's reaching the controller (the mappings seem to work) but fails then. If the solutions bellow don't work could you pack the app and send it to me?

This is the contents of my applicationContext.xml file:

Uh oh. Not in dispatcher-servlet.xml?

<context:component-scan base-package="com.gordonjl"/> <context:annotation-config />

<dwr:annotation-config/>

If you are just instantiating DWR beans that is exactly the same as:

<context:annotation-config /> <dwr:annotation-scan base-package="com.gordonjl" />

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

<dwr:url-mapping />

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

From IWebMvc2 (just to be sure)

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="1" /> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" p:order="2" />

When I replace the <dwr:url-mapping /> with this:

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="alwaysUseFullPath" value="true"/> <property name="order" value="3"/> <property name="mappings"> <props> <prop key="/engine.js">dwrController</prop> <prop key="/util.js">dwrController</prop> <prop key="/interface/**">dwrController</prop> <prop key="/call/**">dwrController</prop> <prop key="/dwr/**">dwrController</prop> </props> </property> </bean>

If you specify alwaysUseFullPath then you must map the full path (/dwr...)

I still get the above error:

2009-01-08 14:09:41,210 DEBUG [org.springframework.web.servlet.DispatcherServlet] - DispatcherServlet with name 'dispatcher' received request for [/test/dwr] 2009-01-08 14:09:41,210 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Bound request context to thread: org.apache.catalina.connector.RequestFacade@3a23cb 2009-01-08 14:09:41,211 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Testing handler adapter [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter@1e01f7 ] 2009-01-08 14:09:41,211 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@3a23cb 2009-01-08 14:09:41,211 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Could not complete request javax.servlet.ServletException: No adapter for handler [org.directwebremoting.spring.DwrController@6be60b]: Does your handler implement a supported interface like Controller?

The call to /util.js will return a 404, btw.

At this point, I'd like to resolve why the test pages aren't working--that's blocking my development--, but it would be nice to have the SpringServlet mapping issue resolved so I can keep my web.xml as clean as possible. What gives?

The test page should be placed at http:// <server>:<port>/<app_name>/<dispatcher_servlet_mapping>/test/<remoted_name>

Thanks,

On Thu, Jan 8, 2009 at 4:25 AM, Jose Noheda <jose@gmail.com>wrote:

AFAIK you can't completely remove the XML files. With your current configuration the most you can achieve is

@RemoteProxy( creator = SpringCreator.class, creatorParams = @Param(name = "beanName", value = "remoteTest"), name = "RemoteTest" )

and declare all the classes. Other option would be to keep your current code and use <dwr:annotation-config /> but that involves XML. By the way DwrServlet is not mandatory when using annotations.

Regards,

On Thu, Jan 8, 2009 at 2:22 AM, John Gordon < john@gordonjl.com> wrote:

Hey, folks,

Is there a way to have a DWR RemoteProxy class work with Spring annotated injection? Here's my situation.

I have a class I want DWR to use that uses an injected class. Spring will be managing the injection. I've been able to do this by defining a bean in Spring's configuration as follows:

<bean id="echoService" class="com.gordonjl.dwr.InjectedServiceImpl"/>

<bean id="remoteTest" class="com.gordonjl.dwr.RemoteTestImpl"> <constructor-arg ref="echoService"/> <dwr:remote javascript="remoteTest"> <dwr:include method="echo"/> </dwr:remote> </bean>

and I'm using the spring-aware DWR servlet to make it possible for DWR to use spring configs:

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

Here's where my issue comes in. I don't like config files. In fact, I despise and want to get rid of them. I'm able to remove config files for my Spring components by using Spring's annotations. In the above spring config code for RemoteTestImpl, I would do this:

@Component public class RemoteTestImpl implements RemoteTest {

private InjectedService theService;

@Autowired public RemoteTestImpl(InjectedService theService) { this.theService = theService; }

public String echo(String echoText) { return theService.echo(echoText); } }

This works just great, but, in order to get rid of the spring config, I need to use DWR's annotations, too. This is what I think I should have after applying the dwr annotations to the above class:

@Component @RemoteProxy public class RemoteTestImpl implements RemoteTest {

private InjectedService theService;

@Autowired

public RemoteTestImpl(InjectedService theService) { this.theService = theService; }

@RemoteMethod public String echo(String echoText) { return theService.echo(echoText); } }

The problem with this is that the documentation for using DWR annotations says that I have to use org.directwebremoting.servlet.DwrServlet and provide the classes it is to parse. My concern is that this DwrServlet isn't spring aware. It will find the classes, read the dwr annotations and, when a remote call is made, it will instantiate the Remote class directly, not through the Spring framework. The result of this is that the injected class in the constructor wouldn't be injected. That leads me to two questions:

Is there yet a servlet for DWR that reads annotations _and_ that accesses the classes through the Spring framework? Is there also a niftier way parse DWR annotated classes instead of explicitly stating them in the web.xml file?

Thanks,