Tuesday, May 18, 2010

dwr 3.0 with Spring 3.0

dwr 3.0 is still in development stages but after checking out dwr 2.0 which requires XML configuration I was willing to take the risk of diving into a release candidate library under heavy development.

web.xml

  1:   <context-param>
  2:     <param-name>contextConfigLocation</param-name>
  3:     <param-value>/WEB-INF/applicationContext.xml</param-value>
  4:   </context-param>
  5:   <listener>
  6:     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  7:   </listener>
  8:   <servlet>
  9:     <servlet-name>dispatcher</servlet-name>
 10:     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 11:     <load-on-startup>2</load-on-startup>
 12:   </servlet>
 13:   <servlet-mapping>
 14:     <servlet-name>dispatcher</servlet-name>
 15:     <url-pattern>*.do</url-pattern>
 16:   </servlet-mapping>
 17:   <servlet-mapping>
 18:     <servlet-name>dispatcher</servlet-name>
 19:     <url-pattern>*.html</url-pattern>
 20:   </servlet-mapping>
 21:   <servlet-mapping>
 22:     <servlet-name>dispatcher</servlet-name>
 23:     <url-pattern>/dwr/*</url-pattern>
 24:   </servlet-mapping>




Notice there is no DwrServlet. Everything goes to Spring’s DispatcherServlet



dispatcher-servlet.xml



  1: <?xml version="1.0" encoding="UTF-8"?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4:   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  5:   xmlns:context="http://www.springframework.org/schema/context"
  6:   xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
  7:   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  8:        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
  9:      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
 10:        http://www.springframework.org/schema/context
 11:        http://www.springframework.org/schema/context/spring-context-2.5.xsd
 12:        http://www.directwebremoting.org/schema/spring-dwr 
 13:        http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd">
 14: 
 15:   <!-- Annotation-based configuration-->
 16:   <context:annotation-config />
 17: 
 18:   <!--
 19:     To remove the explicit bean definitions: Spring can scan package names
 20:     to find beans to manage as follows
 21:   -->
 22:   <context:component-scan base-package="*" />
 23: 
 24:   <!-- Enable DWR AJAX functionality-->
 25:   <dwr:configuration />
 26:   <dwr:annotation-config />
 27:   <dwr:annotation-scan />
 28:   <dwr:url-mapping />
 29:   <dwr:controller id="dwrController" debug="true" />
 30: 
 31:   <!--AnnotationMethodHandler-->
 32:   <bean
 33:     class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
 34:   <!-- bean
 35:     class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /-->



  • Note line number 6, 12, 13. This is to enable DWR namespace


  • Note the order of lines 25-29. If you miss annotation-scan your bean converters will not work and instead of the JSON output you will get the following error



  • I have commented line 9.  This issue has more to do with Spring configuration than DWR. Since you are specifying the AnnotationMethodHandlerAdapter the normally provided (by default) BeanNameUrlHandlerMapping is no longer provided (Spring does not provide it if another handler is specified. Error message thrown is :-



    • 2010-05-18 09:21:39,640 ERROR [dispatcher]:{StandardWrapperValve.java:253} - Servlet.service() for servlet dispatcher threw exception

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


          at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:982)


          at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:770)


          at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)


          at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)


          at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)


          at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)


          at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)


          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)


          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)


          at edu.yale.its.tp.cas.client.filter.CASFilter.doFilter(CASFilter.java:401)


          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)


          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)


          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)


          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)


          at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)


          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)


          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)


          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)


          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)


          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)


          at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)


          at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)


          at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)


          at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)


          at java.lang.Thread.run(Thread.java:595)


    • Read more here :






DwrService



  1: package service.impl;
  2: 
  3: import java.util.ArrayList;
  4: 
  5: import org.directwebremoting.annotations.RemoteMethod;
  6: import org.directwebremoting.annotations.RemoteProxy;
  7: import org.springframework.beans.factory.annotation.Autowired;
  8: import org.springframework.stereotype.Service;
  9: 
 10: import beans.Printer;
 11: import dao.jdbc.VmecsDaoJdbc;
 12: 
 13: @Service
 14: @RemoteProxy
 15: public class DwrService {
 16: 
 17: 	@Autowired
 18: 	private DaoJdbc db;
 19: 
 20: 
 21: 	@RemoteMethod
 22: 	public ArrayList<Printer> getPrinters() {
 23: 		return this.db.getPrinters();
 24: 	}
 25: }


Bean converter



  1: package beans;
  2: 
  3: import org.directwebremoting.annotations.DataTransferObject;
  4: import org.directwebremoting.annotations.RemoteProperty;
  5: import org.directwebremoting.convert.BeanConverter;
  6: 
  7: @DataTransferObject(converter = BeanConverter.class)
  8: public class Printer {
  9: 	@RemoteProperty
 10: 	private String printerName;
 11: 	@RemoteProperty
 12: 	private String queueName;
 13: 
 14: 	/**
 15: 	 * @return the printerName
 16: 	 */
 17: 	@RemoteProperty
 18: 	public String getPrinterName() {
 19: 		return this.printerName;
 20: 	}
 21: 
 22: 	/**
 23: 	 * @param printerName
 24: 	 *            the printerName to set
 25: 	 */
 26: 	public void setPrinterName(String printerName) {
 27: 		this.printerName = printerName;
 28: 	}
 29: 
 30: 	/**
 31: 	 * @return the queueName
 32: 	 */
 33: 	@RemoteProperty
 34: 	public String getQueueName() {
 35: 		return this.queueName;
 36: 	}
 37: 
 38: 	/**
 39: 	 * @param queueName
 40: 	 *            the queueName to set
 41: 	 */
 42: 	public void setQueueName(String queueName) {
 43: 		this.queueName = queueName;
 44: 	}
 45: 
 46: }


Browse to the test page:-



image



Enter input (if required) and hit Execute. The output is JSON



image



I have not explained the annotations since they seem to be self-explanatory. If you have any questions leave a comment.

8 comments:

  1. Hi,

    It is a nice document. Can u give a example for combo box.

    ReplyDelete
  2. I keep getting the exception: "org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [annotation-scan]". What other JARs to you include in addition to DWR 3.0M1? Or is there a DWR JAR that has the required bean definitions?

    ReplyDelete
  3. Followup: DWR 3.0-RC1-116 resolves the issue I mentioned a few minutes ago. However, I now get "javax.servlet.ServletException: No adapter for handler [org.directwebremoting.spring.DwrController@76e1db]: Does your handler implement a supported interface like Controller?". Would this mean that @Service should instead (or additionally) have @Controller?

    ReplyDelete
    Replies
    1. Can u pls provide me the repository link for downloading DWR 3.0-RC1-116

      Thanks in advance

      Delete
  4. At present there is no difference between @Service and @Controller Spring annotations. Please post your complete code and send me the link. I can take a look

    ReplyDelete
  5. Naveen, Sorry I missed your comment - Are you still looking out for a combo box?

    ReplyDelete
  6. Hi,

    Thanks for the good article.

    Can you please post the DaoJdbc class ?

    Thanks

    ReplyDelete
  7. https://java.net/downloads/dwr/

    ReplyDelete

Thank you for your feedback