9

你好(对不起我的英语)

我正在开发使用 SPRING MVC 生成 json 的 web 服务的 angularjs 前端网站。spring mvc 使用 JsonIdentityInfo 选项进行序列化,因此每个对象只在 json 中写入一次,并且每次使用引用,例如她有 2 台“计算机”使用相同的对象“组件”,所以 spring 将 id 放入第一个组件 ("@componentID": 2) 和第二个组件的 id ( 2 ) :

[
  {
    "@computerID": 1,
    "component": {
      "@componentID": 2,
      "processor": 2,
      "ram": "8g",
      "harddrive": "wd"
    }
  },
  {
    "@computerID": 3,
    "component": 2
  }
]

我想要的是 :

[
  {
    "@computerID": 1,
    "owner" : "Mister B",
    "component": {
      "@componentID": 2,
      "processor": 2,
      "ram": "8g",
      "harddrive": "wd"
    }
  },
  {
    "@computerID": 3,
    "owner" : "Mister A",
    "component": {
      "@componentID": 2,
      "processor": 2,
      "ram": "8g",
      "harddrive": "wd"
    }
  }
]

我多次搜索执行此操作的代码,但我没有找到任何想法。

我无法编辑用于删除此行为的 Web 服务。我可以使用 javascript 或 jquery(或其他库)在客户端编辑 json 以用真正的引用对象替换引用吗?(数据实际上更复杂更深,我在对象中有 3 级子对象)。

多谢。

4

2 回答 2

29

我最近遇到了 OP 在此处描述的确切场景。以下是我的解决方案。使用 JSOG(Javascript Object Graph)格式来解决这个问题。

服务器端使用 Jackson-Jsog 插件https://github.com/jsog/jsog-jackson 并使用以下注释对每个类进行注释。

@JsonIdentityInfo(generator=JSOGGenerator.class)

而不是

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")

这将以 JSOG 格式生成。(@id@ref)

在客户端,使用jsog.js

使用以下调用将 JSOG 结构转换为循环结构

cyclicGraph = JSOG.decode(jsogStructure);

于 2014-07-10T18:57:11.590 回答
2

将所有数组成员拆分为新数组:具有完整component属性(不仅仅是数字)的那些和没有的。循环遍历剩下的应该只有数字component属性的原始成员,然后从“好”数组中查找对应@componentID的,并进行一些复制和移动。

// 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));

你会注意到我实际上做了三个数组,但最终只填充了两个:final有你好的新对象,另一个 ( bad) 是没有组件属性的对象的包罗万象,或者其组件编号对应的 @componentID找不到。

于 2014-06-13T15:54:35.247 回答