1

I have POJO class like this

class Data {
    @JsonAlias({"username", "name"})
    String surname;
    Type type;
}

enum Type{
    PERSON, USER
}

I want serialization of the Data class but when type is PERSON, JSON property surname is name and when type is USER, surname field as the name

Actually, I can create more child classes of Data class but my real type is more than 10 types with different names, and only difference is name of JSON property and do work similar.

Mohsen
  • 438
  • 5
  • 14

1 Answers1

2

Probably the simplest option would be to use com.fasterxml.jackson.annotation.JsonAnyGetter annotation. Create a method which returns Map<String, String> and create pair which meets your condition. Below code shows how it could look like:

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.Objects;

public class DataApp {
    private final static JsonMapper JSON_MAPPER = JsonMapper.builder()
            .enable(SerializationFeature.INDENT_OUTPUT)
            .addModule(new JavaTimeModule())
            .build();

    public static void main(String[] args) throws Exception {
        List<Role> roles = List.of(new Role("John", Type.USER), new Role("Tom", Type.PERSON));
        JSON_MAPPER.writeValue(System.out, roles);
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Role {

    @JsonIgnore
    String name;
    Type type;

    @JsonAnyGetter
    private Map<String, String> createDynamicProperties() {
        if (Objects.isNull(type)) {
            return Map.of();
        }
        return switch (type) {
            case USER -> Map.of("name", name);
            case PERSON -> Map.of("surname", name);
        };
    }
}

enum Type {
    PERSON, USER
}

Above code prints:

[ {
  "type" : "USER",
  "name" : "John"
}, {
  "type" : "PERSON",
  "surname" : "Tom"
} ]

See also:

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146