NoisyFlasher
NoisyFlasher

Reputation: 188

Jackson field serialization based on another field

Considering I have such model:

public class Model {

    private String master;
    private Integer slave;
    private String notImportantField1;
    private String notImportantField2;
    private String notImportantField3;
    private String notImportantField4;
    private String notImportantField5;
    private String notImportantField6;
    private String notImportantField7;
    private String notImportantField8;
    private String notImportantField9;
    private String notImportantField10;
    private String notImportantField11;
    private String notImportantField12;
    private String notImportantField13;
    private String notImportantField14;
    private String notImportantField15;

    public void setMaster(String master) {
        this.master = master;
    };
    public String getMaster() {
        return master;
    };

    public void setSlave(Integer slave) {
        this.slave = slave;
    };
    public Integer getSlave() {
        return slave;
    };

    /** 
    * Similar getters/setters for other fields
    */
}

What I want is that after serialization value of "slave" field should be different type depending on "master" field value. For example, having condition:

masterCondition = master.equals("string");

If "masterCondition" is true the result JSON is:

{
    "master": "master_value",
    "slave": "1234567890",
    **And all other fields as they are.**
}

As you can see, we have string value in "slave" field. If "masterCondition" is false the result JSON is:

{
    "master": "master_value",
    "slave": 1234567890,
    **And all other fields as they are.**
}

As you can see, in the second response we have integer value in "slave" field.

I tried to use class-level serializer and it works for me but but these approach produce a lot of boilerplate code for "notImportantFields" and not-null checking.

Also I tried to use ContextualSerializer but it looks that there is no way to get value of another field if I use such serializer on field-level. Is there a way to implement such behavior without boilerplate code? Thanks!

Upvotes: 2

Views: 1955

Answers (1)

Sasha Shpota
Sasha Shpota

Reputation: 10300

You can cheat Jackson by declaring "smart" getter for the slave field.

Declare getter like this:

public Object getSlave() {
    if( "string".equals(master)) {
        return String.valueOf(slave);
    } else {
        return slave;
    }
}

Jackson will convert it in runtime depending on exact type of the returned value.

Upvotes: 4

Related Questions