W3apps home
Software development and training
Home | Products | Services | Support | Careers | Company

Server Communication in JavaFX

JavaFX provides all the tools necessary for server communication. Two main classes used to exchange data between JavaFX client and server are HTTPRequest class to send and receive data and a PullParser to parse the incoming XML or JSON data.

But what we need is a DataMapper utility to convert JavaFX object to XML or JSON string that can be sent to the server and a function to initialize a JavaFX objects from XML or JSON strings receiving from the server.

 

JavaFX data mapping utility

In this artical we will discuss how to build the dataMapper utility.


Say we have a Person class in our applicaiton:

    class Person {
    var firstName:String;
    var lastName:String;
    var age: Integer;
    var isStudent : Boolean;
}

and the  instance of a class:

var person = Person {
    firstName:"John"
    lastName: "Doe"
    age: 20
    isStudent: true
}

To send this object to server, we need to create the followign JSON String:

     {"firstName" : "John", "lastName" : "Doe", "age": 20, "isStudent": true }
 

The server could similar JSON string and we would like to iniatilize JavaFX object using the data in the string.

Our DataMapper utility class can be defined as follows:

    class DataMapper {
        var dataString : String;   //JSON data
        var fxObject : Object; // JavafX object
        function initFx(): Void; //Initialize fxObject from dataString
        function toJson() : String;  // Create JSON string from fxObject
        }

To create a JSON string, we create a DataMapper class and call the toJson method as follows:

var mapper : DataMapper = DataMapper {
                            fxObject: person;
                            }

var jstring: String = mapper.toJson();    //create JSON string

To initialize JavaFX object , we create a DataMapper object and call the initFx() method as follows:

var person : Person = Person {}; //Empty JavaFX object
var jsonData = "\{ \"firstName\":\"John\", \"lastName\":\"Doe\", \"age\":10,  \"isStudent\":true \}";
var mapper : DataMapper = DataMapper {
                            dataString: jsonData;
                            fxObject: person; //object to be initialized
                            }
mapper.initFx();  //Initialize fx object
The code below shows the DataMapper uitility. The tutorials explain the details of how reflectino API work.


package tutorialprojects;


import javafx.data.pull.PullParser;
import java.io.ByteArrayInputStream;
import javafx.data.pull.Event;
import javafx.reflect.FXObjectValue;
import javafx.reflect.FXLocal.Context;
import javafx.reflect.FXLocal;
import javafx.reflect.FXLocal.ClassType ;
import javafx.reflect.FXVarMember;
import java.util.List;


/**
 * @author Tushar.Kale@w3aps.com
 */

class Person {
    var firstName:String;
    var lastName:String;
    var age: Integer;
    var isStudent : Boolean;
}

class Mapper {

    var dataString : String;   //JSON data
    var fxObject : Object; // JavafX object

    //variagles for using reflection
    var local: FXLocal = new FXLocal();
    var context: Context = local.getContext();
    var fxVarMember: FXVarMember;
    var localClassType: ClassType;
    var objectValue: FXObjectValue;

    var bin : ByteArrayInputStream;  //For PullParser


    function initFx(): Void
    {
        bin = new ByteArrayInputStream(dataString.getBytes());
        localClassType = context.makeClassRef(fxObject.getClass());
        objectValue = context.mirrorOf(fxObject);

        def parser = PullParser {
        documentType: PullParser.JSON;
        input: bin;
        onEvent: function(event: Event) {
        if (event.type == PullParser.START_VALUE) {
            fxVarMember =  localClassType.getVariable(event.name);
        } else if (event.type == PullParser.TEXT) {
            fxVarMember.setValue(objectValue, context.mirrorOf(event.text));
        } else if (event.type == PullParser.INTEGER) {
            fxVarMember.setValue(objectValue, context.mirrorOf(event.integerValue));

        } else if (event.type == PullParser.TRUE) {
            fxVarMember.setValue(objectValue, context.mirrorOf(event.booleanValue));

        } else if (event.type == PullParser.NUMBER) {
            fxVarMember.setValue(objectValue, context.mirrorOf(event.numberValue));
        }
        }
    }
    parser.parse();
    }

function toJson() : String  {

        var varName: String;
        var varValue: String;
        var varType: String;  //type of variable Integer, String etc

        var t: ClassType = context.makeClassRef(fxObject.getClass());
        var ov: FXLocal.ObjectValue = new FXLocal.ObjectValue(fxObject,  context) ;
        var variables: List = t.getVariables(true);

        var sb: StringBuffer = new StringBuffer("\{");  //Beginning of JSON object
        try {
        for (item in variables) {
            fxVarMember = item as FXVarMember;
            varName = fxVarMember.getName();
            varType = fxVarMember.getType().toString();

            println("name={varName}  type = {varType}");

            if (indexof item > 0)
            {
                sb.append(", "); //Don't want comma for the first entry but need after every variable
            }
            sb.append(varName).append(": ");
            if(varType.indexOf("java.lang.String") >= 0)
            {  //put double quotes
                varValue = fxVarMember.getValue(ov).getValueString();
                sb.append("\"").append(varValue).append("\"");
            } else {
                    varValue = fxVarMember.getValue(ov).getValueString();
                    sb.append(varValue);
            }
        }
         sb.append("\}");

        } catch ( ex : java.lang.NullPointerException ) {
            println("null  pointer detected!");
            throw ex;
        }

        return sb.toString();
    }
}
Comments: 
 
Home | Company | Products | Support | Services | Careers | Press Release
©2009 W3apps Corporation. All rights reserved.