【问题标题】:deserialize Jackson object in JavaScript containing JsonIdentityInfo在包含 JsonIdentityInfo 的 JavaScript 中反序列化 Jackson 对象
【发布时间】:2014-08-04 04:21:00
【问题描述】:

你好(对不起我的英语)

我正在开发使用 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级子对象)。

非常感谢。

【问题讨论】:

  • 您尝试过我的解决方案了吗?这是我在小提琴中回答的代码:jsfiddle.net/rodgolpe/5e7Vn/2
  • Edit你好。非常感谢您的帮助。我尝试了它并适用于第一个示例;)但我正在尝试根据我的实际用例调整您的解决方案。我得到了像这样的更复杂的数据:pastebin.com/Jk2eNbLK 我引用的对象可以是标本、媒体集、测定、分类单元、recolte、本地化、地层。我尝试将当前对象的名称与之前的列表进行比较,如果它是引用,我使用 getObjects 返回好的内容,然后用好的内容替换引用。
  • -1 用于发布错误的样本数据,让我优雅地解决这个问题,并继续与您合作解决问题,然后不给我积分!
  • 你说得对,我应该在第一时间发布好的数据,对不起。谢谢你所有的时间。我不知道积分是如何工作的。
  • 如果我的回答解决了您最初的问题,您将我的回答标记为“接受”,我将获得积分。更重要的是,其他试图解决类似问题的人会看到它已经被回答,并且可能会发现我的回答(和我们的讨论)很有用。

标签: javascript json spring angularjs jsonidentityinfo


【解决方案1】:

我最近遇到了 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);

【讨论】:

  • 谢谢 - jsog 非常漂亮。
  • JSOG 真的很酷。但是由于杰克逊反序列化器的工作方式,AFAIK 反序列化仍然不起作用(?)......
  • 简单,平滑地集成在 Spring 服务器端(通过 Maven)和 AngularJS 客户端(通过 bower)!
  • 是的,反序列化仍然是一个问题......序列化工作得很好。
  • 这很好用。我将 JsonIdentityInfo 注释仅用于使用 mixin 进行序列化。
【解决方案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 的组件号。

【讨论】:

  • 我看到这是直接的解决方案。为到达单个端点添加 200 行代码仍然是愚蠢的。
  • 哈,@SimonFakir -- 不包括样本component 数据,我数了 48 行。其中 14 个是 getObjects() 实用程序。
猜你喜欢
  • 1970-01-01
  • 2021-10-05
  • 2019-03-27
  • 2015-10-26
  • 1970-01-01
  • 2012-06-14
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多