Java Callout: handling of messageContext value objects?

Looking at the MessageContext object in my Java callout, and I see that the MessageContext interface specifies a `ctx.setVariable(String,Object)` method. I am curious how non-string objects are handled as flow variables.

For instance, if I have the following code:

JSONObject fooObject = doSomeWork();
messageContext.setVariable("foo",fooObject);

I see that this is allowed by the interface ... how is this flattened to be accessible by downstream policies?

My hope is that in future policies I could access the variable in a json-path-ish way as such:

{foo.the[2].path}

Alternatively, is it better to iterate through the object and flatten it into strings myself before persisting it to the messageContext to ensure that downstream policies can reference that data?

2 1 666
1 REPLY 1

The items set into MessageContext really are objects. They do not get flattened upon insertion.

If a later policy tries to retrieve an item, it will be retrieved as an object.

In some cases a variable reference within a policy expects an object of a specific type, like a Message or similar. An example of this might be the XMLToJSON policy. A PopulateCache policy will dereference a variable, to get the value to store in cache; this value can be of any type. But in many places, a variable reference within a policy implicitly expects a string. In those cases the retrieved object will be coerced to a string. If you have stored a string, then the policy will get the string you stored. In your example, though, retrieving context variable "foo", a policy expecting a string will get something like JSONObject@1fee6fd , which is the default toString() value of the object.

If your JSONObject type is really just a custom type and you would like to "dereference" into that type in later policies, then I suggest that you shred the object and store all the properties as independently readable variables. You could use a JSONPath-like notation as the names of the context variables, though it wouldn't really be JSONPath.

I like your idea of being able to use JSONPath on a JSON String, implicitly. But, that isn't possible today. (We're looking into it; the ticket number is APIRT-3489) . Also it would at least require you to store the JSON representation of the object, rather than the object itself. Eg, Something generated by the jackson ObjectMapper.writer().writeValueAsString() method. Stay tuned on this.