仅反序列化选定的属性名称(Jackson)

时间:2016-04-22 08:06:25

标签: java json jackson deserialization

让我们说我们遵循JSON,

{
    "id": "imgsId1",
    "type": "Fruits",
    "name": "Tropical",
    "image":
     {
         "url": "images/img1.jpg",
         "width": 300,
         "height": 300
    },
    "thumbnail":
    {
        "url": "images/thumbnails/img11.jpg",
        "width": 50,
        "height": 50
    }
}

在Java Class中,我们所有字段都与上面的JSON匹配。

每次要反序列化的字段列表取决于发送信息的客户。

例如,对于客户1,我们只想回读以下值(即使在JSON中提供也跳过其他属性)

String[] propertiesToFilter1 = {"type","image.url"};

例如,对于客户2,我们希望回读以下值(并跳过其他属性,即使在JSON中提供)

String[] propertiesToFilter2 = {"type","image.url", "image.width"};

使用Jackson反序列化JSON时,是否可以提供上面的数组,其中包括需要反序列化的字段,

ImageInfo obj1 = (ImageInfo)objectMapper.readValue(jsonStr, ImageInfo.class);

更新

在研究网络时,我看到其中一个选项可能是通过使用

FilterProvider filterProvider = new SimpleFilterProvider().addFilter("filterName1", 
                    SimpleBeanPropertyFilter.serializeAllExcept(propertiesToFilter1));

objectMapper.setFilters(filterProvider);

但我认为这很好,如果我们想继续重复使用相同的" filterName1"适用于多个客户。

在这种情况下,它有点不同,因为我们自定义每个客户可以更新的字段列表。因此,每个客户都有不同的JSON字段列表,他们可以在不同的类中更新。

如果我们开始为每个客户定义不同的过滤器名称,那么它将是一个很长的列表,查找会对性能产生影响。

所以我正在寻找解决方案,在使用objectMapper.readValue()方法构造后退对象时,我可以检查允许在运行时处理的字段列表。

更新2(2016年4月25日):

通过其他杰克逊的问题,在这里看到了类似的问题,

Jackson Dynamic filtering of properties during deserialization

通过创建自定义"静态ObjectMapper"使用下面列出的方法,这种方法的问题是我们多次运行Reflection API。

  • Jackson解析器第一次使用填充所有字段 将JSON反序列化为Java对象时的Reflection API

  • 第二次,因为我们无法获取所有填充的字段 Jackson解析器,为了将数据填充到另一个对象中,我们再次需要运行Reflection API来填充另一个对象。

这可能导致很多开销。

使用上面提供的链接定义的方法,我认为使用" BeanDeserializerModifier"似乎是最好的方法。现在的问题是,既然我们也在使用基于工厂的方法来初始化ObjectMapper,我们也不想为不同的客户硬编码所有数组。

想要检查是否可以为String []数组提供要在运行时考虑的属性列表,以及#34; BeanDeserializerModifier"?

类似的东西,

String[] propertiesToFilter2 = {"type","image.url", "image.width"};

BeanDeserializerModifier curBeanDeserializerModifier = 
            getBeanDeserializerModifierInstance();

curBeanDeserializerModifier.setPropertiesToConsider(propertiesToFilter2);

由于

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

我不确定是否有可能使用注释动态配置反序列化。

我建议创建一个static ObjectMapper的课程。在这个类中,您可以创建反序列化的不同实现。然后,应用程序的业务逻辑应决定哪个实现应该用于哪个客户。在您的不同实现中,您可以像使用注释一样配置ObjectMapper

第二种解决方案可以是为每个客户反序列化完整的json,并让业务逻辑决定使用Pojo的哪些字段/对象。这还需要在您的应用程序中实现。

在业务逻辑中实现配置的好处是,您将拥有更清晰的代码以及为每个客户完成配置的地方。

static ObjectMapper information