【问题标题】:what is the best way to merge two java beans in RESTful API?在 RESTful API 中合并两个 java bean 的最佳方法是什么?
【发布时间】:2015-06-05 01:04:45
【问题描述】:

场景很简单: UI 调用 RESTful API 获取对象树,然后 UI 更改一些数据并调用 RESTful API 进行更新。

但出于安全或性能原因...,我的 RESTful API 无法将整个对象树带到 UI。

为此,我们有两种选择:为 RESTful API 创建单独的 Java Bean 或扩展现有业务 Java Bean 以及 @JsonIgnore。

第二个看起来更聪明,因为我们重用了商务舱。

但是现在我们遇到了一个问题:我需要将 UI 中的对象与 DB 中的对象合并,否则会丢失一些数据。

但是我怎么知道哪条数据会来自 UI? 我知道我可以硬编码来一一复制字段。 但是这种方式很危险。

我要求使用通用方法来避免使用硬代码复制字段。

我尝试了org.apache.commons.beanutils.BeanUtils,但由于它总是覆盖目标字段,它无法满足要求。

所以我是这样想的:
如果 UI bean 中的字段不是 Null,则覆盖目标 bean 中同名字段的值。但是,如果该字段是某种原始类型,例如 int,其默认值为 0,我该如何处理? 我不知道该字段是否真的带有 UI 值 0 或者只是没有从 UI 中返回。

我尝试将原始类型转换为对象类型,但布尔类型仍然存在问题,许多java工具不支持“布尔isValid(){…}”,如BeanUtils。而且这种转换对现有代码很危险。

我尝试了这些代码:

JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClass.construct(MyClassDTO.class, ai, null);
    String[] ignoredList = ai.findPropertiesToIgnore(ac);       
    for(String one: ignoredList){
        System.out.println(one);
    }

但ignoredList 始终为null。我正在使用杰克逊 1.9.2

【问题讨论】:

  • 你能用反射来做吗?就像读取 ui-bean 中的所有字段并将它们传输到数据库 bean 一样?能举个简单的例子吗?
  • 致 Ria:我知道如何以通用方式合并 java bean,但我需要知道哪些字段来自 UI。
  • 好吧,我明白了。只是一些头脑风暴:向传输对象添加一个列表,其中包含用户更改的字段名称?

标签: java rest merge jackson javabeans


【解决方案1】:

我在 Jackson 上找到了解决方案:

MyBean defaults = objectMapper.readValue(defaultJson, MyBean.class);
ObjectReader updater = objectMapper.readerForUpdating(defaults);
MyBean merged = updater.readValue(overridesJson);

它来自:

readerForUpdating

merging on Jackson

【讨论】:

    【解决方案2】:

    您可以考虑使用JsonPatch。我们使用它并且效果很好。当然,这意味着您在 JSON 级别而不是直接在 bean 中应用补丁,因此如果您需要支持的不仅仅是 JSON,这可能是个问题。

    这是一个实现:https://github.com/fge/json-patch

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-16
      • 2010-12-22
      • 2020-09-13
      相关资源
      最近更新 更多