deserialize Jackson object in JavaScript containing JsonIdentityInfo
Solution 1:
I recently came across an exact scenario that OP has described here. Below was my solution. Use JSOG (Javascript Object Graph) format to solve this.
Server Side Use Jackson-Jsog plugin https://github.com/jsog/jsog-jackson and annotate each class using below annotation.
@JsonIdentityInfo(generator=JSOGGenerator.class)
instead of the
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
this would generate in JSOG format. (@id
and @ref
)
On the Client Side, use the jsog.js
convert the JSOG structure to the cyclic one using the below call
cyclicGraph = JSOG.decode(jsogStructure);
Solution 2:
Split all the array members into new arrays: those with a full component
attribute (not just a number) and those without. Loop through the remaining original members which should have just numerical component
attributes, then look up the corresponding @componentID
from the "good" array, and do some copying and moving.
// initialize some vars
var final = [], temp = [], bad = [],
c = {},
computers = [
{
"@computerID": 1,
"component": {
"@componentID": 2,
"processor": 2,
"ram": "8g",
"harddrive": "wd"
}
},
{
"@computerID": 3,
"component": 2
}
];
// split original array into 3: final, bad, & temp
while(computers.length > 0) {
c = computers.pop();
if (c.hasOwnProperty("component")) {
if (typeof c.component === "number") {
temp.push(c);
} else {
final.push(c);
}
} else {
bad.push(c);
}
}
// loop through temp & look up @componentID within final
while (temp.length > 0) {
c = temp.pop();
// should @componentID be 1-of-a-kind?
var found = getObjects(final, "@componentID", c.component);
if (found.length) {
c.component = found[0];
final.push(c);
} else {
bad.push(c);
}
}
// SOURCE: http://stackoverflow.com/a/4992429/1072176
function getObjects(obj, key, val) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
objects.push(obj);
}
}
return objects;
}
// should result in just one or two populated arrays: final and/or bad
alert(JSON.stringify(final));
You'll note I actually made THREE arrays, but only two end up populated: final
has your good new objects, and the other one (bad
) is a catch-all for objects without a component attribute, or for whose component number a corresponding @componentID cannot be found.