我可以在Java Jackson中在反序列化过程中忽略基于getter的只写属性吗?

huangapple go评论80阅读模式
英文:

Can I ignore a getter-based write-only property during deserialization in Java Jackson?

问题

以下是翻译好的内容:

我有一个遗留的 JSON API 类,我正在逐步修改以删除特定的属性。目前情况是,该属性的值始终是相同的常量,因此我希望我的 Java 代码只是一个简单的 getter,而没有底层字段。在我确定所有客户端都已迁移到不再使用该值之前,我希望继续序列化该值。该对象仅由我的客户端读取,因此我不必担心它们发送其他值。

public class MyType {
  private String value;

  public boolean isLegacyValue() {
    return true;
  }
}

也就是说,我不希望任何测试代码等在反序列化具有现在常量属性的完整值时失败。我是否可以告诉 Jackson 仅序列化 setter 方法而在反序列化时忽略它?我尝试了一些不同的方法,但在反序列化时会得到 UnrecognizedPropertyException。我不想为了这个属性而更改全局的 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES

{"value": "ABC", "legacyValue": true}

另一种可接受的方法是告诉 Jackson 在不包括 Java 字段的情况下包括该值。

我知道我可以除了我的 setter 外添加一个 getter,或者将其作为字段,但这两个选项都感觉会使 Java API 变得混乱,因为它实际上并不匹配常量约束:

public void setLegacyValue(boolean legacyValue) {
    // 仅用于 Jackson 反序列化的空操作
}

通过试错发现的一种可行方法是将其设置为 final 字段。出于某种原因,Jackson 知道以一种不需要匹配的 setter 的方式处理它,将其视为只写的常量。如果没有仅通过 getter 完成就无法使用。如果没有仅使用 getter 的方法,这将是我的解决方案。

private final boolean legacyValue = true;

public boolean isLegacyValue() {
    return legacyValue;
}
英文:

I have a legacy JSON API class that I'm evolving to remove a certain property. It's currently at a point where the property value is always the same constant, so I would like my Java code to be just a simple getter with no underlying field for it. I want to continue serializing the value until I know that all my clients have migrated off of using the value. The object is only read by my clients, so I don't have to worry about them sending other values across.

public class MyType {
  private String value;

  public boolean isLegacyValue() {
    return true;
  }
}

That said, I don't want any test code or the like to fail if I deserialize a full value with the now-constant property. Is there a way I can tell Jackson to serialize a setter method-only property, but ignore it on deserialization? I tried a few different things, but I get a UnrecognizedPropertyException on deserialization. I'd rather not change the global DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES just for this one property.

{"value": "ABC", "legacyValue": true}

Also acceptable would be a way to tell Jackson to include the value without including a Java field for it.

I'm aware I can add a getter in addition to my setter, or make it a field, but both those options feel like they're confusing the Java API, as it's not actually matching the constant constraint:

public void setLegacyValue(boolean legacyValue) {
    // No-op; only exists for Jackson deserialization
}

One thing I've found to work through trial and error is making it a final field. For whatever reason, Jackson knows to handle that as a write-only constant in a way that doesn't work with the getter without matching setter. This will be my solution if there's no way to do it with just a getter.

private final boolean legacyValue = true;

public boolean isLegacyValue() {
    return legacyValue;
}

答案1

得分: 1

Jackson支持使用@JsonPropertyaccess参数来定义“单向”属性(即只读或只写属性)。像这样注释您的属性:

@JsonProperty(access = READ_ONLY)
public boolean isLegacyValue() {
    return true;
}
英文:

Jackson supports "one-way" properties using the access parameter of @JsonProperty. Annotate your property like this:

@JsonProperty(access = READ_ONLY)
public boolean isLegacyValue() {
    return true;
}

huangapple
  • 本文由 发表于 2020年5月4日 23:22:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/61595704.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定