JSON-Formatted Data

Top  Previous  Next

The JsonInterface object allows FreeFlyer users to easily import and export JSON-formatted data. JSON, or JavaScript Object Notation, is a data file format that contains attribute-value pairs. For more information on working with different data and file formats, see the Interfacing with Files page and the Parsing Arbitrary String Data page.

 

 

Serializing and Deserializing JSON-formatted data


The JsonInterface object in FreeFlyer provides methods for easily serializing (writing) and deserializing (reading) data to/from JSON format. The JsonInterface object is always used with a Struct that will contain the data to serialize to JSON format (or the data that has been deserialized from JSON format).

 

The examples below use these simple JSON snippets as an input:

 

String jsonString1 =  '{"FirstName": "James", "LastName": "Smith", "Age": 27, "Address":  "21 2nd Street, New York, NY 10021", "Children": [],               "Spouse": null}';

 

String jsonString2 =  '{"FirstName": "Kate",  "LastName": "Smith", "Age": 34, "Address": "106 4th Street, New York, NY 10021", "Children": ["Joe", "Emily"], "Spouse": "Adam"}';

 

In order to use the JSON-parsing functionality in FreeFlyer, the schema of the JSON data must be known in advance. You'll need to define a Struct whose fields will map to the data in the JSON data, as shown below. For the example JSON snippets shown above, we'll define a Struct called "Person" that contains fields for the person's name, age, address, spouse, and children's names:

 

Struct Person;

 String FirstName;

 String LastName;

 Variable Age;

 String Address;

 String Spouse;

 StringArray Children;

End;

 

To deserialize data from a JSON-formatted string or file into a Struct, use the JsonInterface.Deserialize() or JsonInterface.DeserializeFromFile() methods. For this example, now that the Person Struct has been defined, we can create instances of the Person ("James" and "Kate"). Then, we deserialize the data from the JSON-formatted strings into the Structs:

 

Person James;

Person Kate;

 

JsonInterface json;

json.Deserialize(jsonString1, James);

json.Deserialize(jsonString2, Kate);

 

Report James.FirstName, James.LastName, James.Age, James.Address, James.Children, James.Spouse;

Report Kate.FirstName,  Kate.LastName,  Kate.Age,  Kate.Address,  Kate.Children,  Kate.Spouse;

 

This resulting report looks like this:

 

 

To serialize data from a Struct into a JSON-formatted string or file, use the JsonInterface.Serialize() or JsonInterface.SerializeToFile() methods. The example below demonstrates creating a new instance of the Person Struct ("Jane") and populating the Struct fields manually, then serializing the Struct to JSON format:

 

Person Jane;

 

Jane.FirstName = "Jane";

Jane.LastName  = "Smith";

Jane.Age       = 31;

Jane.Address   = "10 3rd Street, New York, NY 10021";

Jane.Spouse    = "Henry";

Jane.Children  = {"Anne""Alice"};

 

Report json.Serialize(Jane, 1); // the "1" tells FreeFlyer to use formatting with newlines and indentation

 

This results in the following JSON-formatted string:

 

{

    "FirstName": "Jane",

    "LastName": "Smith",

    "Age": 31.0,

    "Address": "10 3rd Street, New York, NY 10021",

    "Children": [

        "Anne",

        "Alice"

    ],

    "Spouse": "Henry"

}

 

The JsonInterface object also provides properties to let you specify how FreeFlyer should handle any properties that contain null values or are missing from the Struct.

 

 

Mapping JSON data types to FreeFlyer object types


The table below summarizes the mapping between JSON data types and FreeFlyer object types.

 

JSON Data Type

FreeFlyer Object Type

null

Variable with value matching @JsonNullValue annotation value

Boolean

Variable with @JsonNumericType("bool") annotation

Number

Variable

String

String, TimeSpan

Array

List, Array, StringArray, or TimeSpanArray

Object

Struct

 

Annotations (using the @ symbol) can be specified immediately before a field inside a Struct definition to control how that field is serialized to JSON format.

 

@JsonNullValue - This gives users the ability to create JSON-formatted data that contains null values. The user can specify the value that will correspond to "null."

@JsonNumericType - This gives users the ability to create JSON-formatted data that contains Boolean or integer-formatted values.

@JsonIgnore - This is used to tell FreeFlyer not to include a particular field when serializing/deserializing from JSON format.

@JsonPropertyName - This allows you to specify the property name that will be used for a field in the JSON format. If this annotation is not specified, then the JSON property name must exactly match the Struct field name.

 

These annotations are demonstrated below:

 

// Define a Struct that demonstrates the JSON annotations

 

Struct testAnnotations;

 

 @JsonNullValue(0)

 Variable nullTest;

 

 @JsonNumericType("bool")

 Variable boolTest;

 

 @JsonNumericType("int")

 Variable intTest;

 

 @JsonNumericType("decimal")

 Variable decimalTest;

 

 @JsonIgnore

 Variable ignoreTest;

 

 @JsonPropertyName("test name with spaces")

 Variable test_name_no_spaces;

 

End;

 

The following example shows the definition for a Struct containing each of the various types of data that can be serialized to JSON format. Due to the use of the "extends" keyword, this Struct will also include all of the fields of the testAnnotations Struct defined above.

 

// Define the Struct

 

Struct testDataTypes extends testAnnotations;

 

 Array arrayTest;

 

 String stringTest;

 

 StringArray stringArrayTest;

 

 TimeSpan timeSpanTest;

 TimeSpanArray timeSpanArrayTest;

 

 Person personTest;

 

 List<Person> listTest;

 

 // Complex types will not be serialized to JSON format:

 Matrix matrixTest;         

 Spacecraft spacecraftTest;

 

End;

 

In the script snippet below, we create an instance of the testDataTypes Struct, assign some values into the various member data, and serialize the Struct to JSON format:

 

// Create an instance of the Struct

testDataTypes test;

 

// Assign some values

test.nullTest = 0;

test.boolTest = 1;

test.intTest = 37;

test.decimalTest = 37.3;

test.ignoreTest = 25;

test.test_name_no_spaces = 12;

test.arrayTest = {1, 2, 3, 4};

test.matrixTest = Matrix.Identity(2);

test.stringTest = "hello world";

test.stringArrayTest = {"a""b""c""d"};

test.timeSpanTest = TimeSpan.FromSeconds(5);

test.timeSpanArrayTest = {TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2)};

test.personTest = Kate;

test.listTest.Count = 2;

test.listTest[0] = James;

test.listTest[1] = Jane;

test.spacecraftTest.A = 9000;

 

// Serialize to JSON format

Report json.Serialize(test, 1);

 

The resulting JSON-formatted string is shown below. Note how the various FreeFlyer object types map to different JSON data types, as expected.

 

{

   "nullTest": null,

   "boolTest": true,

   "intTest": 37,

   "decimalTest": 37.3,

   "test name with spaces": 12.0,

   "arrayTest": [

       1.0,

       2.0,

       3.0,

       4.0

   ],

   "stringTest": "hello world",

   "stringArrayTest": [

       "a",

       "b",

       "c",

       "d"

   ],

   "timeSpanTest": "5.000000000",

   "timeSpanArrayTest": [

       "1.000000000",

       "2.000000000"

   ],

   "personTest": {

       "FirstName": "Kate",

       "LastName": "Smith",

       "Age": 34.0,

       "Address": "106 4th Street, New York, NY 10021",

       "Children": [

           "Joe",

           "Emily"

       ],

       "Spouse": "Adam"

   },

   "listTest": [

       {

           "FirstName": "James",

           "LastName": "Smith",

           "Age": 27.0,

           "Address": "21 2nd Street, New York, NY 10021",

           "Children": [],

           "Spouse": ""

       },

       {

           "FirstName": "Jane",

           "LastName": "Smith",

           "Age": 31.0,

           "Address": "10 3rd Street, New York, NY 10021",

           "Children": [

               "Anne",

               "Alice"

           ],

           "Spouse": "Henry"

       }

   ]

}

 

 

See Also


Structs Guide

Lists Guide

Interfacing with Files Guide

oStringArray Properties and Methods

oFileInterface Properties and Methods

oFileProperties Properties and Methods

oStringTokenizer Properties and Methods

Parsing Arbitrary String Data