Creating JSON variable programatically, without SPIN?

1,544 views
Skip to first unread message

Cristian Mastrantono

unread,
May 6, 2015, 5:10:49 PM5/6/15
to camunda-...@googlegroups.com
Hello everyone,

As I saw in the latest news, Camunda 7.3 will deal with JSON perfectly. So I was wondering how should I define a variable as a JSON variable so I can use it in a sequence flow, for example.

I have read some links [1] and [2], and my question is: using Spin is the only way to achieve this? Or there will be a different approach to set a variable as a String with JSON format and then use it as a JSON inside my process?

Something like this would actually work?

String someJsonString = "{...JSON...}";
ObjectValue typedCustomerValue = Variables.serializedObjectValue(someJsonString).serializationDataFormat("application/json").create();
variables.put("customer", typedCustomerValue ); 

And then

<conditionExpression xsi:type="tFormalExpression">
 <![CDATA[
   ${ customer.prop("age").numberValue() >= 21 }
 ]]>
</conditionExpression>

Thanks!
Cristian.

thorben....@camunda.com

unread,
May 7, 2015, 3:18:49 AM5/7/15
to camunda-...@googlegroups.com
Hi Christian,

with Spin we just provide a library and process engine plugin that makes it easy to work with JSON in processes. Spin provides a variable serializer for the data format "application/json", uses Jackson to process JSON and offers a fluent API that allows things like"${S(customer).prop("age")...}. This is the out-of-the-box solution we provide for JSON processing and we are not planning to provide another one in the near future.

Nevertheless, you can implement the same things the Spin integration does and use your favourite JSON processing library, API, etc.
This requires
* implementing a variable serializer [1] for the serialization format "application/json" and registering it with the engine
* including a library that processes JSON such as Jackson

I can give you some more details, if you want to go in that direction.

Could you please describe your use case further? I'd like to learn why Spin does not work for you. Perhaps we can improve it in some way.

Cheers,
Thorben

[1] http://docs.camunda.org/latest/api-references/javadoc/org/camunda/bpm/engine/impl/variable/serializer/TypedValueSerializer.html

Cristian Mastrantono

unread,
May 7, 2015, 9:33:30 AM5/7/15
to camunda-...@googlegroups.com
Hi Thorben!

Thanks for your response, it was very enlightening. I was thinking on using the gson library, but just because that's the library we are using in our project. I have no idea I had to register the serializer with the engine.

That being said, I'll give it a try to Spin and I'll let you know.

Regarding using JSON in Camunda 7.3, can you confirm that after creating a JSON variable through Spin this code will actually work?

<conditionExpression xsi:type="tFormalExpression">
 <![CDATA[
   ${ customer.prop("age").numberValue() >= 21 }
 ]]>
</conditionExpression>

Note that there is no "S(variable)"  as said in [1]  "Now that we introduce Json variables as native ValueTypes, you can directly access the properties of a Json variable in conditions:"

Thanks again
Cristian.

thorben....@camunda.com

unread,
May 7, 2015, 10:24:06 AM5/7/15
to camunda-...@googlegroups.com
Hi Cristian,

Yes, that is possible, however it depends on how you create the typed variable value. There are different options for different uses:

1) object values

The code

String someJsonString = "{...JSON...}";
ObjectValue typedCustomerValue = Variables.serializedObjectValue(someJsonString).serializationDataFormat("application/json").create();
variables.put("customer", typedCustomerValue );

creates an object value. That means, whenever you access the deserialized value (as in the expression), the engine tries to deserialize the value to a java object. In this case, this would fail since we haven't specified a Java type name. The correct code would be

String someJsonString = "{...JSON...}";
ObjectValue typedCustomerValue = Variables.serializedObjectValue(someJsonString).serializationDataFormat("application/json").objectTypeName("com.example.Customer").create();
variables.put("customer", typedCustomerValue );

Then, the expression ${S(customer)...} makes no sense, because customer is already deserialized as an instance of Customer, so you would rather write ${customer.someMethod()...}.

Serializing json as an object value is useful when you need a strongly-typed Java representation.

2) string values

You can submit variables as String values

variables.put("customer", "{Json ... }");

and use them in expressions like ${S(customer)...}.

3) spin values

This is the option discussed in the blogpost you have linked. You have to create the variable like

String someJsonString = "{...JSON...}";
JsonValue typedCustomerValue = org.camunda.spin.plugin.variable.SpinValues.jsonValue(someJsonString).serializationDataFormat("application/json").create();
variables.put("customer", typedCustomerValue );

This tells the engine to use a different serializer (in contrast to option 1) that does not deserialize the variable to a user-specified Java object but to a Spin wrapper object. Then you can use ${ customer.prop("age")... } in the expression.

All of these options make use of Spin, but at different points and for different purposes. Options 2 and 3 are quite similar but 3 saves you the need to create the Spin wrapper yourself by writing S(..) in your expression.

The last option is not yet covered by the user guide and we have a ticket for that ;)

I hope that clarifies the options a little more.

Cheers,
Thorben

Cristian Mastrantono

unread,
May 7, 2015, 2:22:57 PM5/7/15
to camunda-...@googlegroups.com
Awesome! 
I will go for sure with option 2 or 3 ... now I get it ;)

Thanks again!
Cristian.
Reply all
Reply to author
Forward
0 new messages