Question

I would like to pass a complete JSON object to a java adapter in worklight. This adapter will call multiple other remote resources to fulfill the request. I would like to pass the json structure instead of listing out all of the parameters for a number of reasons. Invoking the worklight procedure works well. I pass the following as the parameter:

{ "parm1": 1, "parm2" : "hello" }

Which the tool is fine with. When it calls my java code, I see a object type of JSObjectConverter$1 being passed. In java debug, I can see the values in the object, but I do not see any documentation on how to do this. If memory serves me, the $1 says that it is an anonymous inner class that is being passed. Is there a better way to pass a json object/structure in adapters?

Was it helpful?

Solution 2

To better explain what I'm doing here, I wanted to be able to pass a javascript object into an adapter and have it return an updated javascript object. Looks like there are two ways. The first it what I answered above a few days ago with serializing and unserializing the javascript object. The other is using the ScriptableObject class. What I wanted in the end was to use the adapter framework as described to pass in the javascript object. In doing so, this is what the Adapter JS-impl code looks like:

function add2(a) {
return { 
    result: com.ibm.us.roberso.Calculator.add2(a)
};

The javascript code in the client application calling the above adapter. Note that I have a function to test passing the javascript object as a parameter to the adapter framework. See the invocationData.parameters below:

function runAdapterCode2() {
// x+y=z
var jsonObject = { "x": 1, "y" : 2, "z" : "?" };

var invocationData = {
    adapter : "CalculatorAdapter",
    procedure : 'add2',
    parameters :  [jsonObject]
};

var options = {
    onSuccess : success2, 
    onFailure : failure, 
    invocationContext : { 'action' : 'add2 test' }
};

WL.Client.invokeProcedure(invocationData, options); 
}

In runAdapterCode2(), the javascript object is passed as you would pass any parameter into the adapter. When worklight tries to execute the java method it will look for a method signature of either taking an Object or ScriptableObject (not a NativeObject). I used the java reflection api to verify the class and hierarchy being passed in. Using the static methods on ScriptableObject you can query and modify the value in the object. At the end of the method, you can have it return a Scriptable object. Doing this will give you a javascript object back in the invocationResults.result field. Below is the java code supporting this. Please note that a good chunk of the code is there as part of the investigation on what object type is really being passed. At the bottom of the method are the few lines really needed to work with the javascript object.

@SuppressWarnings({ "unused", "rawtypes" })
public static ScriptableObject add2(ScriptableObject obj) {
    // code to determine object class being passed in and its heirarchy
    String result = "";
    Class objClass = obj.getClass();
    result = "objClass = " + objClass.getName() + "\r\n";
    result += "implements=";
    Class[] interfaces = objClass.getInterfaces();
    for (Class classInterface : interfaces) {
        result += " " + classInterface.getName() ;
    }
    result += "\r\nsuperclasses="; 
    Class superClass = objClass.getSuperclass();
    while(superClass != null) {
        result += " " + superClass.getName();
        superClass = superClass.getSuperclass();
    }

    // actual code working with the javascript object
    String a = (String) ScriptableObject.getProperty((ScriptableObject)obj, "z");
    ScriptableObject.putProperty((ScriptableObject)obj, "z", new Long(3));

    return obj;
}

Note that for javascript object, a numeric value is a Long and not int. Strings are still Strings.

Summary There are two ways to pass in a javascript object that I've found so far.

  1. Convert to a string in javascript, pass string to java, and have it reconstitute into a JSONObject.
  2. Pass the javascript object and use the ScriptableObject classes to manipulate on the java side.

OTHER TIPS

Lets assume you have this in adapter code

function test(){
    var jsonObject = { "param1": 1, "param2" : "hello" };

    var param2value = com.mycode.MyClass.parseJsonObject(jsonObject);

    return {
        result: param2value
    };
}

Doesn't really matter where you're getting jsonObject from, it may come as a param from client. Worklight uses Rhino JS engine, therefore com.mycode.MyClass.parseJsonObject() function will get jsonObject as a org.mozilla.javascript.NativeObject. You can easily get obj properties like this

package com.mycode;

import org.mozilla.javascript.NativeObject;

public class MyClass {

    public static String parseJsonObject(NativeObject obj){
        String param2 = (String) NativeObject.getProperty(obj, "param2");
        return param2;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top