AsyncFW (FWDirect) – Is the Frameworks version of DWR

 

DWR (or Direct Web Remote-ing) is an Apache Open source project. It is an awesome tool and AYNCFW is not designed to compete or replace it. AsyncFW, is simply a lightweight solution to solve a similar problem – Invoking server side java class methods from client side JavaScript.  While none of the code is based on the DWR Source - the concepts are similar, but the implementation is unique.  

 

Why use FWDirect? (or DWR for that matter)

 

This might best be answered with a simple example.  Let’s say you have a class on your server that performs Zip-Code look-up and validation. Now you are being asked to create a new webpage to collect user Zip-Codes.  During your design, you decide that you want to display the name of the corresponding State once the user navigates away from the zip code.  With AYNCFW, from the java script, you could code something like the following to return the associated State value from the server side class named ‘ZipValidator()’;

 

var MyClass = new ZipValidator();

 

var State = MyClass.getState(zipCode);

 

Well the magic here is that ZipValidator is a Java (POJO) class on the server.  It is not a servlet, it is not a service - just a plain old java class.  The method, ‘getState(String zip)’, is a member method of the class, and it is being invoked from the JavaScript.

 

Virtually any class, that you make available,  can be accessed directly from your JavaScript

 

Magic?

 

I called this ‘Magic’ for a reason – as with all magic, this is simply an illusion.  In reality what is happening is very pedestrian. First we are creating a JavaScript Object named MyClass from an object named ZipValidator (More on where this comes from later). Then we are making an Ajax call to a servlet on the server, which is creating an instance of the class and invoking the method, and returning the results.

 

To understand where all the plumbing is, and how it gets created and invoked, we need to take step back from the example, and look at what is required to setup AYNCFW – from the setup, a lot will be come clear. Once we have a working example,  we will loop back around to the “magic”.

 

Setup

 

Assumptions:

 

1)     IDE – Eclipse

2)     Web server – GlassFish

3)     Java 1.5+

4)     FrameWork version 1.3 Installed and working.

 

 

Adding AYNCFW is rather simple, first we need to modify the Web.xml file of your project to include the following;

 

 

  <servlet>

    <description></description>

    <display-name>FWDirect</display-name>

    <servlet-name>FWDirect</servlet-name>

    <servlet-class>com.FW.direct.FWDirect</servlet-class>

    <load-on-startup>0</load-on-startup>

  </servlet>

  <servlet-mapping>

    <servlet-name>FWDirect</servlet-name>

    <url-pattern>/FWDirect</url-pattern>

  </servlet-mapping>

 

 

 

FWDirect & FWDirectX:

 

FWDirect is the servlet that process method requests to class that implement FWDirectX. FWDirectX is an abstract class which implements the methods that will be manipulated by the properties files.

 

 

public abstract class FWDirectX implements DirectAccessInterface{

 

    private boolean allowDirectAccess = false;

    private boolean Dedicated = false;

    private boolean Shared = false;

   

     @Override

     public boolean isAllowDirectAccess() {

          // TODO Auto-generated method stub

          return allowDirectAccess;

     }

 

     @Override

     public boolean isDedicated() {

          // TODO Auto-generated method stub

          return Dedicated;

     }

 

     @Override

     public boolean isShared() {

          // TODO Auto-generated method stub

          return Shared;

     }

    

     @Override

     public void setAllowDirectAccess(String access) {

          if(access.trim().toLowerCase().equalsIgnoreCase("true")){

              allowDirectAccess = true;

          }else{

              allowDirectAccess = false;

              Shared = false;

              Dedicated = false;

          }

     }

     @Override

     public void setDedicated(String dedicated) {

          // TODO Auto-generated method stub

          if(dedicated.trim().equalsIgnoreCase("true")){

              Dedicated = true;

              Shared = false;

          }else

              Dedicated = false;

     }

 

     @Override

     public void setShared(String shared) {

          if(shared.trim().equalsIgnoreCase("true")){

              Shared = true;

              Dedicated = false;

          }else

              Shared = false;

     }

 

Configuring FWDirectX (AYNCFW)

 

A class must be defined in your application’s properties files before it will be made available to the web. This is a simple security control that requires some forethought to implement.  One major difference between DWR and the Framework’s AYNCFW – is the requirement that all classes to be accessed, must extend the FWDirectX abstract class.

 

NOTE: New in the 1.3 release of the Framework is the implementation of the ‘Properties – Mini-framework’,  click here for General information. 

 

By default, classes are not available via AYNCFW, unless you configure them as such – see below;

 

 

DESCRIPTION=This is the configuration for the FrameWork

 

class.com.FW.properties.DBProps   = DBProps

 

DBProps.setUser                   = n/a

DBProps.setPassword               = n/a

.

.

.

 

class.com.test.TestDirect         = TestDirect

TestDirect.setAllowDirectAccess   = true

TestDirect.setDedicated           = false

TestDirect.setShared              = false

 

 

In the sample FWDefualt.properties files, you can see the class com.FW.test.TestDirect is being made available to the Framework, and on load, it will execute the .setAllowDirectAccess method, passing in the string value “true”, the setDedicated to ‘false’, and the setShared to ‘false’.  These are the three standard methods provided, and handled by the FWDirectX abstract class. These methods should only be called by the FrameWork, and will only be called once at startup.

 

Method

Value

Comment

setAllowDirectAccess

True/false

When set to true, this class is available to AYNCFW, and it’s getters and setters can be called from the client.

setDedicated

True/ false

When set to true, each session will get it’s own private instance of the class. The class is retained for the lifetime of the session.

setShared

True/ false

When set to true, every session shares one instance of the class – effectively creating a static class.

n/a

n/a

If both Dedicate, and Shared are false, an instance of the class will be created for every call, and then it will be deleted.

 

 

NOTE: The ‘name’ given to the class ‘com.test.TestDirect’ does not need to match the actual class name.  We could have done the following;

 

class.com.test.TestDirect    = DoIt

DoIt.setAllowDirectAccess    = true

 

IMPORTANT: The EnvProps settings in the FWDefualt.properties file (or your own file) need to also be considered. The following settings will impact how AYNCFW functions in your environment.

 

For Example;

EnvProps.setDirectXTimeout        = 2

EnvProps.setDirectXValidateUser   = false

EnvProps.setDirectXUser           = a

EnvProps.setDirectXPass           = a

 

 

Method

Value

Comment

setDirectXTimeout

Integer

representing minutes to keep session alive if inactive

setDirectXValidateUser

True/ false

Force validation of a session user and password. When set to true, the following two settings must be supplied

setDirectXUser

String

The name of the user to use for FWDirectX sessions – if needed

setDirectXPass

String

The user password to use for FWDirectX sessions – if needed

 

Creating the Class

 

To start using AYNCFW, we will first need a class to talk to. The following is a rather useless example, but it servers our purposes.

 

TestDirect.java

package com.test;

 

import com.FW.direct.DirectAccessInterface;

 

public class TestDirect implements DirectAccessInterface{

    private static String UserName              = "(default)";

    private String UserCity                     = "SomeCity";

    private String userState                    = "SomeState";

   

    public TestDirect(){

     

    }

      public String getUserName() {

           

            return UserName;

      }

      public void setUserName(String userName) {

            System.out.println("\n\n>>>>>>>SET USER NAME:"+userName);

            UserName = userName;

      }

      public Integer getSomeTest(int x, String y, Integer g, Float h, double ii){

            System.out.println("\n int:"+x+"\nString:"+y+"\nInteger:"+g+"\nFloat:"+h+"\ndouble:"+ii);

            return 100;

      }

      public String getUserCity() {

            return UserCity;

      }

 

      public void setUserCity(String userCity) {

            UserCity = userCity;

      }

 

      public String getUserState() {

            return userState;

      }

 

      public void setUserState(String userState) {

            this.userState = userState;

      }

 

}

 

Create a package called com.test and add the above class to it.

Generating the JavaScript

 

Once the properties are configured, start (or restart) the server.  When the FWDirect servlet is loaded by the server, it will create the FWDirect.js JavaScript file. To import the generated script into your application – edit your startup html file to include the following import;

 

<script type="text/javascript" src="./scripts/fw/FWDirect.js"></script>

 

Now, we can start testing.

 

 

Once the Server has started, the generated JavaScript is available. Below is a snippet from the JavaScript file generated for TestDirect;

 

 

 

function TestDirect(){

  this.getUserName = function(xHandler) {

   sysParmTypes = "";

   sysParmValues="";

   xCall(xHandler, 'TestDirect', 'getUserName' ,sysParmValues);

  };

  this.setUserName = function(xHandler,fw0000_String) {

   sysParmTypes = "String";

   sysParmValues="fw0000_String="+fw0000_String;

   xCall(xHandler, 'TestDirect', 'setUserName' ,sysParmValues);

  };

.

.

.

 

 

To use the above class to access the the TestDirect class on the server you would do the following;

 

Function Test(){

var MyClass = new TestDirect();

MyClass.getUserName(“TestHandler”);

}

 

Function TestHandler(returnValue){

            Alert(returnValue);

}

 

 

Notice that we had to include an “Event Handler” function named TestHandler.  Since the AYNCFW is based on Ajax, the response will be returned to this Handler. The response will always be a single string value.  If the called function does not return a value, then the string “void” will be returned. If a null value is returned from the method, it will return to your handler as the string “null”.  Your java script will need to determine how to interpret the returned values.

 

The AYNCFW can handle the following types as either inputs, or return values;

 

1)     String.class

2)     Integer.class

3)     Float.class

4)     Double.class

5)     int.type

6)     float.type

7)     double.type

 

 

NOTE: The AYNCFW supports up to 99 input parameters for each individual method call. Values passed into, and values returned are always Strings, regardless of the actual underlying types. So for example;

 

public Integer getSomeTest(int x, String y, Integer g, Float h, double ii){

.

.

 Return intMyValue;

}

 

 

Would be called from you script as follows;

 

MyClass.getSomeTest(“Handler”, “1”, “Hello World”, “200”, “200.2345”, “1000000000”);

 

Unsupported types

 

Currently the AYNCFW does not support the use of Arrays, or collections of any type as input, or return values.

 

Dedicated and Shared Access

 

In the above example, you will find that doing a “setUserName”, followed by a “getUserName” does very little for you. This is due to the fact that the class is created and destroyed for every call. This may be useful in some situations, but you may sometimes need to persist the data between calls. Here you have three options.

 

1)     Make your methods, and variables static

This gives you the most control over what is static and what is not. However, the values assigned affect every user on the system. Be aware, that if you are in load balanced environment, each environment will have it’s own instance!!!

 

2)     Configure your class as “shared” in the FWDefault.properties file

This makes one copy of the class available to all users.  Same as above, except even non-static values are retained and shared. This is a pseudo- static class.

 

3)     Configure your class as “Dedicated” in the FWDefault.properties file

This option gives each session its own instance of the class. Values are retained for each user over the life of the session.

 

Security

 

As with all things related to Security, and the use of the Framework,  it is up to you to test and verify the security, or lack there of. One important thing to keep in mind – The automatic validation feature of the Framework, is turned off for LDRW. So be aware, that while your pages may be secure, your AYNCFW classes may not me.  This was a design decision for the first release – it may change J

 

Conclusion

While you may never use AYNCFW, it presents some interesting opportunities to the web developer.

 

 

 

Copyright 2009. All rights reserved by

S. Chappell