Search code examples
javajsonjacksonjackson-databind

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


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;
}

Solution

  • 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;
    }