Wednesday, January 12, 2011

Spring MVC 3 and DWR 3 Integration Tutorial

In this tutorial we will build a simple Spring MVC 3 application with AJAX capabilities using DWR. We will explore how to convert a simple Spring service bean into a DWR service and access it from a JSP page. We will be developing a non-AJAX application first then convert it to an AJAX-powered version later.

What is DWR?
DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible.

DWR is Easy Ajax for Java

Source: http://directwebremoting.org/dwr/index.html

What is AJAX?
Ajax is a group of interrelated web development methods used on the client-side to create interactive web applications. With Ajax, web applications can retrieve data from the server asynchronously in the background without interfering with the display and behavior of the existing page. Data is usually retrieved using the XMLHttpRequest object. Despite the name, the use of XML is not needed, and the requests need not be asynchronous.

Like DHTML and LAMP, Ajax is not one technology, but a group of technologies. Ajax uses a combination of HTML and CSS to mark up and style information. The DOM is accessed with JavaScript to dynamically display, and to allow the user to interact with the information presented. JavaScript and the XMLHttpRequest object provide a method for exchanging data asynchronously between browser and server to avoid full page reloads.

Source: http://en.wikipedia.org/wiki/Ajax_(programming)

Our application is a simple arithmetic operation that adds two numbers and displays the sum. Here's a screenshot of the non-AJAX version:


Here's a screenshot of the AJAX version:


Notice nothing much is different, except that the non-AJAX version will display the result on another page, while the AJAX version will display on the same page. Actually, this is the main difference! With AJAX we have a responsive, desktop-like application. No page refresh.

Non-AJAX Version

Let's develop first our non-AJAX Spring MVC application.

We need a controller to handle the user's requests. Let's call it NonAjaxController

NonAjaxController
package org.krams.tutorial.controller;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.krams.tutorial.service.ArithmeticService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Handles and retrieves the main requests
 */
@Controller
@RequestMapping("/main/nonajax")
public class NonAjaxController {

 protected static Logger logger = Logger.getLogger("controller");
 
 @Resource(name="springService")
 private ArithmeticService springService;
 
    /**
     * Handles and retrieves the non-AJAX, ordinary Add page
     */
    @RequestMapping(value="/add", method = RequestMethod.GET)
    public String getNonAjaxAddPage() {
     logger.debug("Received request to show non-AJAX, ordinary add page");
    
     // This will resolve to /WEB-INF/jsp/nonajax-add-page.jsp
     return "nonajax-add-page";
 }
    
    /**
     * Handles request for adding two numbers
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(@RequestParam(value="inputNumber1", required=true) Integer inputNumber1,
           @RequestParam(value="inputNumber2", required=true) Integer inputNumber2,
           Model model) {
  logger.debug("Received request to add two numbers");
  
  // Delegate to service to do the actual adding
  // This service is the same service that DWR uses!
  Integer sum = springService.add(inputNumber1, inputNumber2);
  
  // Add to model
  model.addAttribute("sum", sum);
  
     // This will resolve to /WEB-INF/jsp/nonajax-add-result-page.jsp
  return "nonajax-add-result-page";
 }
    
}
This controller declares the following mappings:
/main/nonajax/add (GET) - retrieves the add page
/main/nonajax/add POST) - computes the sum and retrieves the result page
The first mapping receives a request to display the add page. The second mapping receives two numbers and delegates the computation to the ArithmeticService. When the ArithmeticService is done processing, the controller then forwards the result to another JSP page which displays the result.

Here are the JSP pages:

nonajax-add-page.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
 <title>Spring MVC - DWR Integration Tutorial</title>
</head>
<body>

<h3>Spring MVC - DWR Integration Tutorial</h3>
<h4>Non-AJAX version</h4>

<c:url var="addUrl" value="/krams/main/nonajax/add" />
<form method="POST" action="${addUrl}">

Demo 1 
<div style="border: 1px solid #ccc; width: 250px;">
 Add Two Numbers: <br/>
 <input id="inputNumber1" name="inputNumber1" type="text" size="5"> +
 <input id="inputNumber2" name="inputNumber2" type="text" size="5">
 <input type="submit" value="Add" /> <br/>
 Sum: (Result will be shown on another page)
</div>

</form>

</body>
</html>

nonajax-add-result-page.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
 <title>Spring MVC - DWR Integration Tutorial</title>
</head>
<body>

<h3>Spring MVC - DWR Integration Tutorial</h3>
<h4>Non-AJAX version</h4>

<c:url var="addUrl" value="/krams/main/nonajax/add" />
<form method="POST" action="${addUrl}">

Demo 1 
<div style="border: 1px solid #ccc; width: 250px;">
 Add Two Numbers: <br/>
 <input id="inputNumber1" name="inputNumber1" type="text" size="5"> +
 <input id="inputNumber2" name="inputNumber2" type="text" size="5">
 <input type="submit" value="Add" /> <br/>
 Sum: (Result will be shown on another page)
</div>

</form>

</body>
</html>

Let's run the application. We'll be adding two numbers: 5 and 10, and we expect 10 as the result.

To access the Add page, enter the following URL in your browser:
http://localhost:8080/spring-mvc-dwr/krams/main/nonajax/add


Here's the result:

Now let's examine the service that performs the actual processing:

ArithmeticService
package org.krams.tutorial.service;

import org.apache.log4j.Logger;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Service enables the class to be used as a Spring service
 * @RemoteProxy enables the class to be used as a DWR service
 * @Transactional enables transaction support for this clas
 */
@Service("springService")
@RemoteProxy(name="dwrService")
@Transactional
public class ArithmeticService {
 
 protected static Logger logger = Logger.getLogger("service");
 
 /**
  * @RemoteMethod exposes this method to DWR.
  * Your JSP pages can access this method as Javascript
  * Your Spring beans can still access this method.
  */
 @RemoteMethod
 public Integer add(Integer operand1, Integer operand2) {
  logger.debug("Adding two numbers");
  // A simple arithmetic addition
  return operand1 + operand2;
 }
 
}
This is a very simple POJO service that contains a simple arithmetic function. To make this POJO available as a Spring service bean, we just add the @Service annotation.

Notice we've also annotated the class with @RemoteProxy. This enables the same POJO to be utilized by DWR! This means to integrate DWR in our existing application, we don't need to duplicate existing code.

AJAX Version

Let us now convert our non-AJAX application to an AJAX-powered version.

We have already enabled our existing ArithmeticService to be utilized by DWR. That means we just need to create our JSP pages to display the AJAX version of our application. Actually we just need to create one JSP page because both the request and result will be shown on the same page! This is the primary benefit of AJAX. We also need another controller to handle the page request for the AJAX version of our application.

Here is the controller.

AjaxController
package org.krams.tutorial.controller;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.krams.tutorial.service.ArithmeticService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles and retrieves the main requests
 */
@Controller
@RequestMapping("/main/ajax")
public class AjaxController {

 protected static Logger logger = Logger.getLogger("controller");
 
 @Resource(name="springService")
 private ArithmeticService springService;
 
 /**
  * Handles and retrieves the AJAX Add page
  */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String getAjaxAddPage() {
     logger.debug("Received request to show AJAX, add page");
     
     // This will resolve to /WEB-INF/jsp/ajax-add-page.jsp
     return "ajax-add-page";
 }
 
}

Here is the JSP page.

ajax-add-page.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

   <script type='text/javascript' src="/spring-mvc-dwr/krams/dwr/engine.js"></script>
   <script type='text/javascript' src="/spring-mvc-dwr/krams/dwr/util.js"></script>
 <script type="text/javascript" src="/spring-mvc-dwr/krams/dwr/interface/dwrService.js"></script>
 
 <title>Spring MVC - DWR Integration Tutorial</title>
</head>
<body>

<h3>Spring MVC - DWR Integration Tutorial</h3>
<h4>AJAX version</h4>

Demo 1
<div style="border: 1px solid #ccc; width: 250px;">
 Add Two Numbers: <br/>
 <input id="inputNumber1" type="text" size="5"> +
 <input id="inputNumber2" type="text" size="5">
 <input type="submit" value="Add" onclick="add()" /> <br/>
 Sum: <span id="sum">(Result will be shown here)</span>
</div>

<script type="text/javascript">
 // Retrieves the matching value
 // Delegates to the dwrService
 function add() {
  // Retrieve value of text inputs
  var operand1 = dwr.util.getValue("inputNumber1");
  var operand2 = dwr.util.getValue("inputNumber2");
  
  // Pass two numbers, a callback function, and error function
  dwrService.add(operand1, operand2, {
   callback : handleAddSuccess,
   errorHandler : handleAddError
  });
 }

 // data contains the returned value
 function handleAddSuccess(data) {
  // Assigns data to result id
  dwr.util.setValue("sum", data);
 }

 function handleAddError() {
  // Show a popup message
  alert("We can't add those values!");
 }
</script>

</body>
</html>
Notice in the head section, we have included three JavaScript libraries:
<script type='text/javascript' src="/spring-mvc-dwr/krams/dwr/engine.js"></script>
<script type='text/javascript' src="/spring-mvc-dwr/krams/dwr/util.js"></script>
<script type="text/javascript" src="/spring-mvc-dwr/krams/dwr/interface/dwrService.js"></script>

What are these libraries?
DWR comes with some small JavaScript libraries to help you:
  • engine.js: Handles all server communication
  • util.js: Helps you alter web pages with the data you got from the server (and a few neat extras too)
Source: http://directwebremoting.org/dwr/documentation/index.html

The dwrService.js is our ArithmeticService itself! Let's examine how our Java class has been converted to a JavaScript:

dwrService.js
// Provide a default path to dwr.engine
if (typeof this['dwr'] == 'undefined') this.dwr = {};
if (typeof dwr['engine'] == 'undefined') dwr.engine = {};
if (typeof dwr.engine['_mappedClasses'] == 'undefined') dwr.engine._mappedClasses = {};

if (window['dojo']) dojo.provide('dwr.interface.dwrService');

if (typeof this['dwrService'] == 'undefined') dwrService = {};

dwrService._path = '/spring-mvc-dwr/krams';

/**
 * @param {class java.lang.Integer} p0 a param
 * @param {class java.lang.Integer} p1 a param
 * @param {function|Object} callback callback function or options object
 */
dwrService.add = function(p0, p1, callback) {
  return dwr.engine._execute(dwrService._path, 'dwrService', 'add', arguments);
};

Let's examine the JSP page again. Notice it contains two parts: the HTML part that shows the input, and the JavaScript part that handles the AJAX.

HTML part
Demo 1
<div style="border: 1px solid #ccc; width: 250px;">
 Add Two Numbers: <br/>
 <input id="inputNumber1" type="text" size="5"> +
 <input id="inputNumber2" type="text" size="5">
 <input type="submit" value="Add" onclick="add()" /> <br/>
 Sum: <span id="sum">(Result will be shown here)</span>
</div>
This is a simple form that takes two numbers. When the Add button is clicked, the JavaScript add() function is called.

JavaScript part
<script type="text/javascript">
 // Retrieves the matching value
 // Delegates to the dwrService
 function add() {
  // Retrieve value of text inputs
  var operand1 = dwr.util.getValue("inputNumber1");
  var operand2 = dwr.util.getValue("inputNumber2");
  
  // Pass two numbers, a callback function, and error function
  dwrService.add(operand1, operand2, {
   callback : handleAddSuccess,
   errorHandler : handleAddError
  });
 }

 // data contains the returned value
 function handleAddSuccess(data) {
  // Assigns data to result id
  dwr.util.setValue("sum", data);
 }

 function handleAddError() {
  // Show a popup message
  alert("We can't add those values!");
 }
</script>
The add() function is a wrapper to DWR's service named dwrService. Where did we get this name? This is the name we assigned in the ArithmeticService inside the @RemoteProxy
@RemoteProxy(name="dwrService")
@Transactional
public class ArithmeticService {
...
}

The add() function retrieves the value of the form input fields using DWR's utility class dwr.util.getValue():
// Retrieve value of text inputs
  var operand1 = dwr.util.getValue("inputNumber1");
  var operand2 = dwr.util.getValue("inputNumber2");

Then it calls the actual dwrService.add(), passing the two inputs, a callback function to handle the result if successful, a error function to handle error messages:
// Pass two numbers, a callback function, and error function
  dwrService.add(operand1, operand2, {
   callback : handleAddSuccess,
   errorHandler : handleAddError
  });

The success callback function retrieves the result named data. Then we used DWR' utility class again to update an HTML's value with the result.
// data contains the returned value
 function handleAddSuccess(data) {
  // Assigns data to result id
  dwr.util.setValue("sum", data);
 }
Here the sum is the named of the HTML element we assigned earlier in the HTML part:
Sum: <span id="sum">(Result will be shown here)</span>

Let's run our application and check the result.

To access the Add page, enter the following URL in your browser:
http://localhost:8080/spring-mvc-dwr/krams/main/ajax/add


Here's the result:

The result is displayed on the same page. There's no need to create another page just to view the result.

We're almost done with our tutorial. Now we need to add the required XML configuration to enable both Spring MVC and DWR.

To enable Spring MVC and DWR we need to add both in the web.xml

web.xml
<servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <!-- Mapping for Spring MVC  -->
 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>/krams/*</url-pattern>
 </servlet-mapping>

 <!-- Mapping for DWR -->
 <servlet-mapping>
   <servlet-name>spring</servlet-name>
   <url-pattern>/krams/dwr/*</url-pattern>
 </servlet-mapping>
 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
Take note of the URL patterns. We've separated the URL patterns for pure Spring MVC and DWR calls.

In the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.

spring-servlet.xml
<!-- Declare a view resolver -->
 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
      p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

By convention, we must declare an applicationContext.xml as well.

applicationContext.xml
<!-- Activates various annotations to be detected in bean classes -->
 <context:annotation-config />
 
 <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
   For example @Controller and @Service. Make sure to set the correct base-package-->
 <context:component-scan base-package="org.krams.tutorial" />
 
 <!-- Configures the annotation-driven Spring MVC Controller programming model.
  Note that, with Spring 3.0, this tag works in Servlet MVC only!  
  See Spring Reference 15.12 Configuring Spring MVC
  @ http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-annotation-driven-->
 <mvc:annotation-driven /> 
 
 <!-- Without the following adapter, we'll get a "Does your handler implement a supported interface like Controller?"
  This is because mvc:annotation-driven element doesn't declare a SimpleControllerHandlerAdapter
  For more info 
  See http://stackoverflow.com/questions/3896013/no-adapter-for-handler-exception 
  See http://forum.springsource.org/showthread.php?t=48372&highlight=UrlFilenameViewController -->
 <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

 <!-- Loads DWR-related configuration -->
 <import resource="dwr-context.xml" />
We've referenced a separate config file dwr-context.xml that contains DWR-related beans.

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

 <!-- DWR will scan all Spring managed beans containing @RemoteProxy or 
  @RemoteMethod annotations and register Creator proxies for them. 
  This will NOT scan any classes not managed by Spring. -->
 <dwr:annotation-config />

 <!-- DWR will scan the classpath and search classes containing @RemoteProxy or 
  @RemoteMethod annotations. This will register the beans and Creator proxies for these classes.-->
 <dwr:annotation-scan base-package="org.krams.tutorial" scanDataTransferObject="true" scanRemoteProxy="true" />

 <!-- DWR will map util.js and engine.js files to the dwrController.
  You can then include this files as external Javascript references from your JSP -->
 <dwr:url-mapping />

 <!-- Defines the dwrController. During production, set the debug property to false -->
 <dwr:controller id="dwrController" debug="true" />

 <!-- 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: 
  <dwr:configuration> 
   <dwr:convert type="bean" class="org.krams.tutorial.CustomClass" /> 
  </dwr:configuration> -->
 <dwr:configuration />

 <!-- Some articles 
  DWR 2.0.x, Spring 2.x, with Spring MVC
  http://www.butterdev.com/dwr/2008/02/dwr-20x-spring-2x-with-spring-mvc/ -->
</beans>

Conclusion

That's it. We've completed our application. We've managed to build a simple Spring MVC 3 application with AJAX capabilities using DWR. We've reused the same service bean both for MVC and DWR. We've also used some of DWR's utility JavaScript libraries.

The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-dwr/

You can download the project as a Maven build. Look for the spring-mvc-dwr.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

Updates
March 19, 2010
I have updated the Maven project which now includes the following DWR library in the pom.xml file:
    <dependency>
     <groupId>org.directwebremoting</groupId>
     <artifactId>dwr</artifactId>
     <version>3.0.M1</version>
     <type>jar</type>
     <scope>compile</scope>
    </dependency>

The problem with the original Maven project is it uses the latest DWR 3.0.RC1, but it is not available in the Maven repository. So I had to add it manually under the WEB-INF/lib folder. The project works when it's deployed via Eclipse's m2 (Maven) plugin.

However, when it's deployed via the standalone Maven, it complains that some DWR classes are missing. There are a couple of workarounds like adding the library to your local repository. See here: http://stackoverflow.com/questions/2479046/maven-how-to-add-additional-libs-not-available-in-repo. But this would require the user to setup a repo and makes the project not portable.

An alternative approach is to use an older DWR jar. We have to add a Maven reference to an older DWR jar, but we keep the new library under the WEB-INF/lib so that our project will still use the latest jar. For the purpose of this tutorial, you can use this workaround. But for actual development, please use the latest DWR jar (which I use as well for production). To run the application, you still run the same Maven commands:

For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you want to learn more about Spring MVC and integration with other technologies, feel free to read my other tutorials in the Tutorials section.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3 and DWR 3 Integration Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

35 comments:

  1. Very useful, thanks!

    What are the advantages/disadvantages of using DWR vs Spring MVC 3.0 built-in AJAX support (@RequestBody and automatic Model to JSON conversion)?

    ReplyDelete
  2. That's a great question. The main disadvantage of @RequestBody and JSON conversion is you have to know another framework that will handle the response. I've put a tutorial similar to that: http://krams915.blogspot.com/2011/01/spring-mvc-3-and-jquery-integration.html. This one uses JQuery to handle the response. With DWR you can reuse existing Spring services and in the client side, you don't have to learn another framework. You reuse your knowledge of DWR. However I don't really see it as a major disadvantage. It just require extra work. I actually like the JQuery-Response/RequestBody-JSON conversion because it allows me to use JQuery's plugins. However, you can in fact combine DWR and JQuery. At the end, both ways give the same result :)

    ReplyDelete
  3. Could you please check in the code in 'Google Code' ? The repository is empty.

    The code does not seem to run on Jetty or Tomcat, at least not the code attached in the ZIP-file.

    ReplyDelete
  4. @Frode, the project exists in the Google repository. I've updated the Maven project that fixes the issue with the DWR not loading.

    ReplyDelete
  5. The code does not seem to run on Jetty or Tomcat, at least not the code attached in the ZIP-file.

    ReplyDelete
  6. Hello,
    Could you tell me please how can I fix the following problem?
    ..........
    INFO: Initializing Spring root WebApplicationContext
    [ERROR] [main 05:06:45] (ContextLoader.java:initWebApplicationContext:220) Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ajaxController' defined in file [F:\mesEtudes\AutoFormation\jee\spring-mvc-dwr\target\classes\org\krams\tutorial\controller\AjaxController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.krams.tutorial.controller.AjaxController]: Constructor threw exception; nested exception is java.lang.Error: Unresolved compilation problems:
    The import javax.annotation cannot be resolved
    Resource cannot be resolved to a type
    The attribute name is undefined for the annotation type Resource

    Thank you

    ReplyDelete
  7. Thank you for the very nice tutorial! When trying to deploy the example in tomcat 7 I get an exception "[ERROR] [Thread-2 05:55:11] (ContextLoader.java:initWebApplicationContext:220) Context initialization failed
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [annotation-scan]"
    and the app is not available.
    It works with the embedded mvn tomcat:run though. Do you have any suggestions? Thanks!

    ReplyDelete
  8. clear explination and code comments
    Thanks

    ReplyDelete
  9. please help me for solving this probelm in your program download

    Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/validation/ConstraintDescriptor

    ReplyDelete
  10. Actually concerning the "The import javax.annotation cannot be resolved" problem we can fix it by adding the javaee.jar on the project classpath (that jar contains the javax.annotation)

    ReplyDelete
  11. I found the "cleanest/simplest" way to work with DWR is to checkout the trunk:

    svn co http://svn.directwebremoting.org/dwr/trunk/ dwr-trunk

    Run "mvn clean install" on the trunk, which will install the rc3 modules. You can then run the demo against the dwr trunk dependencies as demonstrated by this project:

    http://directwebremoting.org/jira/browse/DWR-544

    ReplyDelete
  12. All your tutorials are good, practical, comprehensive, to the point and help solve real issues. The best postings I've seen. Thanks Ray

    ReplyDelete
  13. hey really your tutorials are very helpful in implementing each and every point in the project.... I have used almost all your tutorial for creating new spring project... Thanks a lot. Is there a way to post you my technical problems apart from your tutorial? If there pls suggest.

    ReplyDelete
  14. @Anonymous, feel free to post your issues here. I would suggest posting the issues related to the tutorial or the topic.

    ReplyDelete
  15. hey i m getting following error on deploying the above application.Can u pls suggest some solution
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [annotation-scan]

    ReplyDelete
  16. @Anonymous, you have to post the full error stack.

    ReplyDelete
  17. I am unable to post my full error stack. is there any other option to do it.

    ReplyDelete
  18. Offending resource: ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Configuration problem: Id is required for element 'annotation-config' when used as a top-level tag
    Offending resource: ServletContext resource [/WEB-INF/dwr-context.xml]
    Offending resource: ServletContext resource [/WEB-INF/dwr-context.xml]
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)

    ReplyDelete
  19. Above is the part of error stack

    ReplyDelete
  20. Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for ele
    ment [annotation-scan]
    Offending resource: ServletContext resource [/WEB-INF/dwr-context.xml]

    Can u give me solution for this error ?

    ReplyDelete
  21. unable to print a collection of data on jsp page. please help.

    ReplyDelete
  22. Thanks a lot for this post. Great work! What would be the modifications need to be done in this project if we want to use Reverse Ajax? Thanks.

    ReplyDelete
  23. Hello, How do I get in touch with you? There is no email or contact info listed .. please advise .. thanks .. Mary. Please contact me maryregency at gmail dot com

    ReplyDelete
    Replies
    1. Check your email. I sent you a message

      Delete
  24. had the same error as anonymous.

    [ERROR] [Thread-18 11:10:37] (ContextLoader.java:initWebApplicationContext:220) Context initialization failed
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [dwr-context.xml]
    Offending resource: ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [annotation-scan]
    Offending resource: ServletContext resource [/WEB-INF/dwr-context.xml]

    ReplyDelete
    Replies
    1. I'm having the same problem. Does this error been solved? Someone kindly post the solution.

      Thanks,

      Ryan

      Delete
    2. I found an article on how to solve this error. Basically, you need to download DWR-3.0.0-rc-SNAPSHOT. If you're using Maven, you need to put it in your pom.xml.

      Here is the article, http://mohansrihari.wordpress.com/2012/08/16/integrating-dwr3-and-spring3/

      Delete
  25. Hi Krams..
    This one was nice article to learn more on the integration of spring mvc with dwr.. I hope this can also be applied to Spring Portlet MVC too. I have one query here. We have some custom tags in jsp. We need to display data with custom tag in the jsp. Can you please let me out if you have already come across this issue.

    ReplyDelete
  26. Hi Krams,

    I read everywhere that common logging is needed to use DWR. We have logback logging, would that be a problem? Thanks!

    Lin

    ReplyDelete
  27. in the jsp page, i see this line:
    type="text/javascript" src="/spring-mvc-dwr/krams/dwr/interface/dwrService.js"

    how do you know the js file will be there as I dont see any config in the xml file that says that when u refer to../interface/.. there will be a a dwrService.js file ?

    ReplyDelete
  28. hi your code working fine, but am trying to integrate same thing to example which is shown in this link http://howtodoinjava.com/2013/03/21/spring-3-and-hibernate-integration-tutorial-with-example/ if possible please can u guide me ????

    ReplyDelete
  29. Hi ,
    in ArithmeticService.java your returning like this {return operand1 + operand2}; but if i want to return a list or object like
    boolean bValue= objUserManager.verifyUserNameAndPassword(firstname, lastname );
    it is not supporting. rather than bvalue dinamic like above, if it is static like bvalue="true" then its working fine... can u please help me out to solve this????

    ReplyDelete
  30. Hi Krams,
    When use same in portlet Environment(Liferay) it is throwing error WebApplicationObjectSupport instance [DWRController@xxxx]does not run within a ServletContext. Make sure the object is fully configured!,
    Please help to resolve this.

    ReplyDelete
  31. Nice article thnks a lot but It would be appreciable if you could have added the DWR effect on server side i.e how we can access javascript of html/jsp pages on server side.

    ReplyDelete
  32. Hi Krams
    Why are you non-ajax jsp code is the same (nonajax-add-page.jsp & nonajax-add-result-page.jsp)?

    ReplyDelete