JAVA/XML based configuration of DWR 3 with Spring MVC 4 and annotations

dwr-logo-200

JAVA/XML based configuration of DWR 3 with Spring MVC 4 and annotations

This post is for people who know working of DWR(Direct Web Remoting) with Spring MVC. In order to understand DWR and kindly follow below post.

http://jkoder.com/direct-web-remoting/

Having understood DWR, let’s configure DWR with Spring MVC version 4 . In this post I will show configurations based on XML and JAVA. Nowadays people are getting fascinated with JAVA based configurations while using Spring framework. I have seen various posts over internet that claims to configure DWR using JAVA configuration, as far as I know, till date DWR does not support JAVA based configuration. However, I will still show you guys the JAVA configuration of DWR 3 with Spring MVC 4, what problem I faced after, and how I resolved it by switching to XML configuration of DWR 3. During this experience I will introduce you guys with annotations provided by DWR 3 library and its ease of use.

First of all I have added support for DWR calls with Spring’s Dispatcher servlet in my MVC initializer class.

@Override
	protected String[] getServletMappings() {
		return new String[] { "/dwr/*","/" };
	}

Below are the java configuration in java based mvc config class.

    @Bean
    public DwrController dwrController(ApplicationContext applicationContext){

        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry)applicationContext.getAutowireCapableBeanFactory();
        Map<String,String> configParam = new HashMap<String, String>();
        configParam.put("activeReverseAjaxEnabled","true");

        ClassPathBeanDefinitionScanner scanner = new DwrClassPathBeanDefinitionScanner(beanDefinitionRegistry);
        scanner.addIncludeFilter(new AnnotationTypeFilter(RemoteProxy.class));
        scanner.addIncludeFilter(new AnnotationTypeFilter(DataTransferObject.class));
        scanner.addIncludeFilter(new AnnotationTypeFilter(GlobalFilter.class));
        scanner.scan("com.quarks");

        DwrController dwrController = new DwrController();
        dwrController.setDebug(true);
        dwrController.setConfigParams(configParam);

        SpringConfigurator springConfigurator = new SpringConfigurator();
        List configurators = new ArrayList();
        configurators.add(springConfigurator);
        dwrController.setConfigurators(configurators);


        return dwrController;
    }

   @Bean
    public BeanNameUrlHandlerMapping beanNameUrlHandlerMapping(){
        BeanNameUrlHandlerMapping beanNameUrlHandlerMapping = new BeanNameUrlHandlerMapping();
        return beanNameUrlHandlerMapping;
    }

    @Bean
    public DwrHandlerMapping dwrHandlerMapping(DwrController dwrController){
        Map<String,DwrController> urlMap = new HashMap<String, DwrController>();*/
        urlMap.put("/dwr/**/*",dwrController);

        DwrHandlerMapping dwrHandlerMapping = new DwrHandlerMapping();
        dwrHandlerMapping.setAlwaysUseFullPath(true);
        dwrHandlerMapping.setUrlMap(urlMap);
        return dwrHandlerMapping;
    }

Below is my AJAX controller class which will receive AJAX calls via DWR. DWR converts this JAVA code into corresponding javascript code and then using it to interact with below JAVA class.

package com.mypack.controller;

import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;

@RemoteProxy(name="ajaxController")
public class MyAjaxController {

	@RemoteMethod
	public String test(String s){
		return s;
	}
}

In the above DWR java configuration we have told DWR to scan through classes and find classes with @RemoteProxy annotation. After finding the class DWR will look for methods with @RemoteMethod. After scanning above annotations DWR creates corresponding javascript code through below URL.

http://localhost:[PORT]/[WEBAPP]/dwr/interface/ajaxController.js

One more thing to add, you need to add policy for DWR calls in your security configuration. I configured no security policy for DWR calls in my java based Spring security configuration.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/dwr/**/*");
}

So after implementing these configurations you can start deploy your application. As per my experience application deployed successfully. I was also able to generate engine.js and util.js using below URLs.

http://localhost:[PORT]/[WEBAPP]/dwr/engine.js
http://localhost:[PORT]/[WEBAPP]/dwr/util.js

However, I was not able to generate ajaxController.js via http://localhost:[PORT]/[WEBAPP]/dwr/interface/ajaxController.js

I did a lot investigation and found that DWR does not support JAVA based configuration. Then, I had to write the same configuration in XML(dwr-config.xml) and import it into my existing Spring MVC java configuration class.

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" xmlns:p="http://www.springframework.org/schema/p" 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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"> 


<!-- DWR Configurations -->
              <dwr:controller id="dwrController" debug="false">
                     <dwr:config-param name="crossDomainSessionSecurity" value="false"/> 
              </dwr:controller>
              
              <!-- Configure DWR handlers -->
              <bean id="dwrUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
              <property name="alwaysUseFullPath" value="true"/>
              <property name="mappings">
                     <props>
                     <prop key="/dwr/**/*">dwrController</prop>
                     </props>
              </property>
              </bean>
       
       <dwr:annotation-config />
       <dwr:annotation-scan base-package="com.mypack" scanDataTransferObject="true" scanRemoteProxy="true" />
       </beans>

You must have noticed scanDataTransferObject=”true”, this configuration will scan for classes with @DataTransferObject annotation. This annotation along with @RemoteProperty annotation prepares a bean that can be transferred to the javascript client as a corresponding javascript object. Refer below. MyBean object will be converted to corresponding javascript object with 3 properties(properties that are annotated with @RemoteProperty).

package com.mypack.beans;

import org.directwebremoting.annotations.DataTransferObject;
import org.directwebremoting.annotations.RemoteProperty;

@DataTransferObject
public class MyBean{

    @RemoteProperty
    private Integer property1;
    @RemoteProperty
    private String property2;
    @RemoteProperty
    private String property3;

    public Integer getProperty1() {
        return property1;
    }

    public void setProperty1(Integer property1) {
        this.property1 = property1;
    }

    public String getProperty2() {
        return property2;
    }

    public void setProperty2(String property2) {
        this.property2 = property2;
    }

    public String getProperty3() {
        return property3;
    }

    public void setProperty3(String property3) {
        this.property3 = property3;
    }
}

Note that if you are using spring version 4 then for XML configuration you have to use spring-dwr3.0 xsd as version 4 of spring-dwr4.0 is not supported. Now let’s import this XML configuration into existing SPring MVC java configuration.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.mypack")
@ImportResource("classpath:dwr-config.xml")
public class MyWebConfiguration extends WebMvcConfigurerAdapter{
//configurations
}

After doing above changes I was good to go with DWR. Happy coding!