当前位置: 首页 > 知识库问答 >
问题:

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

南门星河
2023-03-14

假设我们有以下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匹配的所有字段。

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

例如,对于customer 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”。

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

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

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

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

浏览杰克逊的其他问题,在这里看到了一个类似的问题,

反序列化期间属性的Jackson动态筛选

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

>

  • 将JSON反序列化为Java对象时,Jackson解析器首次使用反射API填充所有字段

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

    这可能会导致大量开销。

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

    想检查是否可以向“BeanDeserializerModifier”提供字符串[]数组以及运行时要考虑的属性列表?

    类似于,

    String[] propertiesToFilter2 = {"type","image.url", "image.width"};
    
    BeanDeserializerModifier curBeanDeserializerModifier = 
                getBeanDeserializerModifierInstance();
    
    curBeanDeserializerModifier.setPropertiesToConsider(propertiesToFilter2);
    

    谢谢

  • 共有2个答案

    欧阳绪
    2023-03-14

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

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

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

    在业务逻辑中实现配置的好处是,您将拥有更干净的代码,并且可以在一个地方为每个客户进行配置。

    静态对象映射器信息

    江天宇
    2023-03-14

    使用@JsonIgnoreProperties和配置参数

    http://www.programcreek.com/java-api-examples/index.php?api=com.fasterxml.jackson.annotation.JsonIgnoreProperties

     类似资料:
    • 问题内容: 如何设置Newtonsoft.Json以使用旧成员名称反序列化对象,但使用当前成员名称序列化该对象? 编辑:一项要求是将过时的成员从要序列化/反序列化的类中删除。 这是一个需要序列化和反序列化的示例对象。我给了一个属性一个属性,该属性包含过去可能已序列化过的名称的列表。 我想始终使用名称“ a”对json进行序列化,但能够从任何旧名称(包括“ alpha”和“ omega”)以及当前名

    • 问题内容: 是否可能:在类中有一个字段,而在Jackson库中进行序列化/反序列化时却为其使用不同的名称? 例如,我有“ Coordiantes”类。 对于从JSON反序列化,希望具有以下格式: 但是当我序列化对象时,结果应该是这样的: 我试图通过在getter和setter上都应用注释(具有不同的值)来实现此目的: 但我有一个例外: org.codehaus.jackson.map.exc.Un

    • 大家好,我想在将Pojo序列化为json时删除属性名。我有以下课程 SubFieldItems类: 当我序列化时,json输出是 但我希望子字段的值不带属性名,如下所示: 我可以使用什么Jackson注释,我已经尝试过在toString方法中使用@JsonValue来强制执行,就像在评论中一样,但是我一直得到奇怪的结果。请提供任何帮助,谢谢。谢谢

    • 关于这个问题: 如何在使用JSON.NET序列化时更改属性名称? 会像预期的那样反序列化。 作为一个解决方案,没有属性也可以工作,或者类上有一个属性,比如:

    • 问题内容: 我面临一个问题。我想反序列化来自服务器的复杂JSON响应,但是我只需要其中一部分。 这是一个例子: 我还使用Csharp2json获取所需的类对象,我只是根据需要修改了菜单类: 现在,如果我只需要popup值和他的孩子,我该如何反序列化? 问题答案: 如果您想尝试一下,可以实际使用NewtonSoft.Json的Linq命名空间,并稍加修改代码以仅从JSON中获取“ popup”元素。

    • 问题内容: 我有以下从外部方收到的JSON字符串。 我的映射类: 现在的问题是,我不喜欢的 类名 和 字段名 的类。相反,我希望它被命名,并且还希望从字段名称中删除并提供适当的名称。 我可以重命名为,但是如果我更改了字段名(在类中),它将无法正确地反序列化并提供给我。我该如何克服呢? 问题答案: Json.NET具有允许您指定JSON属性名称的名称,因此您的代码应为: 文档: 序列化属性