Mapping an array with common properties and dynamic name in Json

Viewed 348

I'm having a problem while trying to create a model from a json which is formed by json arrays that have same properties but different names.

This is an example of json which i want to transform into a model:

{
    "AA": [
        {
            "t": 1605589200,
            "o": 17.37,
            "h": 18.3,
            "l": 17.11,
            "c": 18.28,
            "v": 9578592
        },
        {
            "t": 1605675600,
            "o": 18.3,
            "h": 18.85,
            "l": 18.3,
            "c": 18.575,
            "v": 9092559
        }
    ],
    "AAIC": [
        {
            "t": 1605589200,
            "o": 2.92,
            "h": 3.045,
            "l": 2.92,
            "c": 3.02,
            "v": 550468
        },
        {
            "t": 1605675600,
            "o": 3.11,
            "h": 3.1684,
            "l": 3.03,
            "c": 3.05,
            "v": 476259
        }
    ]
}

Notice that each array has the same object structure but have different names ("AA" and "AAIC"). I already wrote the following code:

@Data
public class SomeClass {

    private List<SomeClassInfo> someClassInfo;

    @Data
    public class SomeClassInfo {

        @JsonProperty(value = "t")
        private Integer time;
        @JsonProperty(value = "o")
        private Double o;
        @JsonProperty(value = "h")
        private Double h;
        @JsonProperty(value = "l")
        private Double l;
        @JsonProperty(value = "c")
        private Double c;
        @JsonProperty(value = "v")
        private Integer v;
    }

}

But it is not enough, because I don't want to make n lists with specific name such as

@JsonProperty(value = "AA")
List<SomeClassInfo> AA;
@JsonProperty(value = "AAIC")
List<SomeClassInfo> AAIC;

since the example above represents 2 of 10k arrays and each array contains n json object with the same structure.

2 Answers

you can use ObjectMapper to wrap your json into

Map<String,List<SomeClassInfo>>

like that

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class test {

    public static void main(String[] args)  {
        ObjectMapper mapper = new ObjectMapper();
        String jsonInput = "{\"AA\":[{\"t\":1605589200,\"o\":17.37,\"h\":18.3,\"l\":17.11,\"c\":18.28,\"v\":9578592},{\"t\":1605675600,\"o\":18.3,\"h\":18.85,\"l\":18.3,\"c\":18.575,\"v\":9092559}],\"AAIC\":[{\"t\":1605589200,\"o\":2.92,\"h\":3.045,\"l\":2.92,\"c\":3.02,\"v\":550468},{\"t\":1605675600,\"o\":3.11,\"h\":3.1684,\"l\":3.03,\"c\":3.05,\"v\":476259}]}";
        TypeReference<HashMap<String, List<SomeClassInfo>>> typeRef
                = new TypeReference<HashMap<String, List<SomeClassInfo>>>() {
        };
        Map<String, List<SomeClassInfo>> map = null;
        try {
            map = mapper.readValue(jsonInput, typeRef);
            System.out.println(map);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

    }

    @Getter
    @Setter
    @ToString
    @Data
    public static class SomeClassInfo {

        @JsonProperty(value = "t")
        private Integer time;
        @JsonProperty(value = "o")
        private Double o;
        @JsonProperty(value = "h")
        private Double h;
        @JsonProperty(value = "l")
        private Double l;
        @JsonProperty(value = "c")
        private Double c;
        @JsonProperty(value = "v")
        private Integer v;
    }
}

and the response will be like that :

{AA=[test.SomeClassInfo(time=1605589200, o=17.37, h=18.3, l=17.11, c=18.28, v=9578592), test.SomeClassInfo(time=1605675600, o=18.3, h=18.85, l=18.3, c=18.575, v=9092559)], AAIC=[test.SomeClassInfo(time=1605589200, o=2.92, h=3.045, l=2.92, c=3.02, v=550468), test.SomeClassInfo(time=1605675600, o=3.11, h=3.1684, l=3.03, c=3.05, v=476259)]}

I found the solution by merging @Hamza Slama solution and others that i finally found at the following link: deserialize json using jackson with dynamic field name

My edited model is:

@Data
public class SomeClass {

    private Map<String, SomeClassInfo[]> someClassInfoMap = new HashMap<>();

    @JsonAnySetter
    public void setSomeClassInfo (String name, SomeClassInfo[] someClassInfo) {
        someClassInfoMap.put(name, someClassInfo);
    }

    @Data
    public static class SomeClassInfo {

        @JsonProperty(value = "t")
        private Integer time;
        @JsonProperty(value = "o")
        private Double o;
        @JsonProperty(value = "h")
        private Double h;
        @JsonProperty(value = "l")
        private Double l;
        @JsonProperty(value = "c")
        private Double c;
        @JsonProperty(value = "v")
        private Integer v;
    }

}

Related