在RESTful API中合并两个java bean的最佳方法是什么?

时间:2015-03-31 15:51:02

标签: java rest merge jackson javabeans

场景很简单: 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工具不支持像BeanUtils这样的“Boolean isValid(){...}”。而这种转换对现有代码来说是危险的。

我尝试了这些代码:

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。我正在使用Jackson 1.9.2

2 个答案:

答案 0 :(得分:0)

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

以下是一项实施:https://github.com/fge/json-patch

答案 1 :(得分:0)

我在杰克逊找到了解决方案:

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

它来自:

readerForUpdating

merging on Jackson