【发布时间】:2016-08-15 18:12:54
【问题描述】:
假设我们有以下 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 类中,我们拥有与上述 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”使用下面列出的方法,这种方法的问题是我们多次运行反射 API。
Jackson 解析器第一次使用 将 JSON 反序列化为 Java 对象时的反射 API
第二次,因为我们无法获取所有由 Jackson 解析器,为了将数据填充到另一个对象中,我们再次需要运行反射 API 来填充另一个对象。
这可能会导致大量开销。
使用上面提供的链接中定义的方法,我认为使用“BeanDeserializerModifier”似乎是最好的方法。现在的问题是,由于我们也使用基于工厂的方法来初始化 ObjectMapper,我们不想为不同的客户硬编码所有数组。
想检查是否可以向 String[] 数组提供运行时要考虑的属性列表给“BeanDeserializerModifier”?
类似的东西,
String[] propertiesToFilter2 = {"type","image.url", "image.width"};
BeanDeserializerModifier curBeanDeserializerModifier =
getBeanDeserializerModifierInstance();
curBeanDeserializerModifier.setPropertiesToConsider(propertiesToFilter2);
谢谢
【问题讨论】:
-
你怎么知道你必须为哪个客户反序列化东西,什么时候不需要?
-
这个 JSON 文件可以通过 Web(表单 POST)或 FTP 接收。对于所有客户,我们使用相同的 Java 类文件。
标签: java json jackson deserialization