This integration is mean for DWR version 2.x.

Overview

DWR is a powerful tool allows Javascript in a browser to interact with Java on a server and helps you manipulate web pages with the results. WebWork integrates with DWR to allow WebWork's action to be invoked through XHR (Ajax) and the results / action made available at the client side (browser).

There's also a page in DWR documentation about WebWork integration at here

Configuration

To configure DWR integration with WebWork, first we need to set up web.xml

<servlet>
    <servlet-name>dwr</servlet-name>
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>org.directwebremoting.extend.AccessControl</param-name>
        <param-value>com.opensymphony.webwork.dwr.WebWorkDwrAccessControl</param-value>
    </init-param>
</servlet>

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

Take note that we need to configure WebWorkDwrAccessControl as the AccessControl. This is due to DWR by default will not allow any classes declared with org.directwebremoting.* to be invoked remotely nor does it allows those classes to be passed as arguments. This is for security reasons. With WebWorkDwrAccessControl, we'll allow org.directwebremoting.webwork.* classes to be invoked and passed as arguments to methods. This is because WebWork and DWR integration code is distributed together with DWR. It doesn't lies within WebWork distribution.

Then we need to configure dwr.xml, which typically resides under /WEB-INF)

<!DOCTYPE dwr PUBLIC
        "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
        "http://getahead.org/dwr//dwr20.dtd">

<dwr>
    <allow>
        <create creator="new" javascript="validator">
            <param name="class" value="com.opensymphony.webwork.validators.DWRValidator"/>
        </create>
        <convert converter="bean" match="com.opensymphony.xwork.ValidationAwareSupport"/>

        <create creator="new" javascript="dwraction">
            <param name="class" value="org.directwebremoting.webwork.DWRAction" />
        </create>
        <convert converter="bean" match="org.directwebremoting.webwork.ActionDefinition"/>
        <convert converter="bean" match="org.directwebremoting.webwork.AjaxResult" />
        <convert converter="bean" match="com.opensymphony.xwork.ActionSupport" />
    </allow>

    <signatures>
        <![CDATA[
        import java.util.Map;
        import com.opensymphony.webwork.validators.DWRValidator;
        import org.directwebremoting.webwork.ActionDefinition;
        import org.directwebremoting.webwork.DWRAction;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.ServletContext;

        DWRValidator.doPost(String, String, Map<String, String>);
        DWRAction.execute(ActionDefinition, Map<String, String>, HttpServletRequest, HttpServletResponse, ServletContext);
        ]]>
    </signatures>
    
</dwr>

Concept

The concept of WebWork/DWR integration is to allow :-

  • WebWork action to be invoked through client side using dwr and the rendered result given back as String
  • WebWork action to be invoked through client side using dwr but the result is not executed, instead the action is exposed, so the client could called any of its exposed methods (following JavaBean spec.) through DWR.

Usage

We need to declare the following script for DWR / WebWork integration to work

Declaration of util.js is optional, but the remaning are crucial.

<script src='<ww:url value="/dwr/interface/dwraction.js" />'></script>
<script src='<ww:url value="/dwr/engine.js" />'></script>
<script src='<ww:url value="/dwr/util.js" />'></script>

Invoke WebWork's Action and execute the result

To invoke WebWork's action and execute its result we'd do

Do take note that we are invoking WebWork action using dwraction, this is due to the fact that it is
declared so in the <script> section as indicated above.

dwraction.execute(
   // An Javascript Object that will be converted to ActionDefinition by DWR
   {
      action: 'myWebWorkAction', // our webwork action name
      namespace: '/myNamespace', // our webwork namespace
      executeResult: true        // let's execute our result as well
   },
   // Parameters we'd like to passed to WebWork's Action
   {
      param1: 'value1', 
      param2: 'value2'
   },
   // our callback function
   function(ajaxResult) {
      // ajaxResult will be DefaultAjaxTextResult (converted to js object by DWR)
      // the executed result (String) will be stored in ajaxResult.text
      document.getElementById("ourDivId").innerHTML = ajaxResult.text;
   }
 );

Invoke WebWork's Action but don't execute its result, instead expose its Action

dwraction.execute(
   // An Javascript Object that will be converted to ActionDefinition by DWR
   {
      action: 'myWebWorkAction', // our webwork action name
      namespace: '/myNamespace', // our webwork namespace
      executeResult: false       // let's NOT execute our result as well
   },
   // Parameters we'd like to passed to WebWork's Action
   {
      param1: 'value1', 
      param2: 'value2'
   },
   // our callback function
   function(ajaxResult) {
      // ajaxResult will be DefaultAjaxDataResult (converted to js object by DWR)
      // the action will be exposed as ajaxResult.data
      // Let's say for example, we have a getter for MyString in our WebWork action, we could do
      // the following to retrieve it
      document.getElementById("ourDivId").innerHTML = ajaxResult.data.myString;
   }
 );

Example

There's an example in WebWork's showcase under the section WebWork DWR integration. Might want to check it out as well.

Debugging

We could turn on debugging as in this example (through debug init-param web.xml), and access

http://host:port/context/dwr/

To see if dwraction interface is exposed properly without any warnings or errors.