【问题标题】:(Jackson 1.9.2) Getting @JsonIgnore to work: deserialization with mixin annotations and polymorphic types(Jackson 1.9.2) 让@JsonIgnore 工作:使用 mixin 注释和多态类型进行反序列化
【发布时间】:2011-12-07 20:22:05
【问题描述】:

我正在尝试反序列化 JSON 字符串,例如(提取此位以显示问题)

{
    "$type": "com.example.StringProperty",
    "value": "hello world",
    "name": "text",
    "readOnly": false
}

进入看起来像的类层次结构

public class Property
{
    public String name;
    public int    type;

    Property(String pName, int pType) { name = pName; type = pType; }
}

public class StringProperty extends Property 
{
    public String value;        
    StringProperty(String pName, String pValue) {
        super(pName, String);
        value = pValue;
    }       
}

使用以下 mixin 注释

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="$type")
abstract public class PropertyMixin
{
    @JsonProperty
    public String name;
    //@JsonIgnore
    //public boolean readOnly;
    @JsonProperty
    public int type;

    PropertyMixin(@JsonProperty("name") String pName, @JsonProperty("type") int pType)
    {
    }
}

abstract public class StringPropertyMixin
{
    @JsonProperty
    public String value;
    //@JsonIgnore
    //public boolean readOnly;

    @JsonCreator
    public StringPropertyMixin(@JsonProperty("name") String pName, @JsonProperty("value") String value)
    {
    }
}

使用 Jackson 1.9.2,我得到的错误是

Unrecognized field "readOnly" (Class com.example.StringProperty), not marked as ignorable

我尝试使用@JsonIgnore,但这并没有帮助(检查我注释掉的代码的位置,看看我是如何尝试的)。我可能遗漏了一些东西,但我认为需要另一双眼睛来看待它并帮助我。

这是反序列化环境的样子:

        objectMapper.setVisibilityChecker(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.NONE)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

        MixinRegistrations module = new MixinRegistrations();
        objectMapper.registerModule(module);

mixin 模块看起来像

@Override
public void setupModule(SetupContext context)
{
    context.setMixInAnnotations(Property.class, PropertyMixin.class);
    context.setMixInAnnotations(StringProperty.class, StringPropertyMixin.class);
}

感谢所有帮助。提前致谢。

PS:我不知道这是否会有所不同,但 JSON 是由用 .Net Framework v4 编写的库生成的。

【问题讨论】:

    标签: java json jackson deserialization


    【解决方案1】:

    我认为 Jackson 遇到了问题,因为您作为创建者委派的方法没有 readOnly 字段的参数。所以与其默默地忽略这个缺失的参数,Jackson 会抛出一个错误(良好的行为)。尝试使用 JsonIgnoreProperties 注释。我以前不需要使用 if,但是对于反序列化,您可以明确表示创建者不需要的字段。

    哦,this 似乎也相关。

    编辑: Another question that the asker found that was useful.

    【讨论】:

    • 是的,如果这是你想要的行为,你可以添加 @JsonIgnoreProperties(ignoreUnknown = true)
    • @Dunes:如果@JsonIgnore 在这种情况下不起作用,@JsonIgnoreProperties 如何提供帮助?看起来 @JsonIgnoreProperties 只是 @JsonIgnore 对多个值的扩展。
    • 我明白为什么 @JsonIgnore 在我的情况下不起作用,但在阅读 this post@JsonIgnoreProperties 工作正常。感谢您指出@JsonIgnoreProperties 注释。
    • @alokoko 区别在于@JsonIgnoreProperties是在类级别添加的,可以用来按名称忽略JSON属性;而@JsonIgnore 只忽略特定属性,并且您必须有一个字段或 setter/getter 才能将其附加到。
    • @StaxMan:“并且您必须有一个字段或设置器/获取器将其附加到”部分很重要。我最初也错过的是,该语句应该读作“并且您必须有一个字段或 setter/getter 将其附加到目标类中”,因为我的 mixin 类中已经有了该字段,但它不起作用.我是在阅读您在another post 的另一条回复后才知道的。
    【解决方案2】:

    请注意,您的问题不是该类具有杰克逊无法识别的属性,而是 JSON 具有一个属性。因此,您可能想阅读this wiki page

    如前所述,@JsonIgnoreProperties 可以在这里使用,因为将注释添加到类不需要字段或设置器,这与@JsonIgnore 不同。此外,它还可用于忽略任何和所有未知属性。

    【讨论】:

    • 感谢您的链接。在您回答前 30 秒,我发表了一条评论,说明我是如何理解事情是如何运作的。 :-)
    【解决方案3】:
    @JsonIgnoreProperties({"propX", "propY"})
    

    在课堂上可以正常工作!

    【讨论】:

      猜你喜欢
      • 2020-11-28
      • 2019-08-10
      • 2014-05-01
      • 2016-09-22
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 2018-10-13
      相关资源
      最近更新 更多