Search code examples
javajsonjacksonsetobjectmapper

Mapping a Json placeholder file to java Object


So I have the following JSON to represent a City object which I want to MAP to an object in JAVA. This is used to filter out unwanted fields

   {
  "class": [
    {
      "id": "default",
      "type": [
        "riskType",
        "firstTime"
      ],
      "direction": [],
      "town": [
        "leader",
        {
          "streets": [
            "mainStreet"
          ]
        }
      ]
    }
  ]
}

To map it I am using a ojectMapper.readValue(inputStream, new TypeReference<HashMap<String, Set<PayloadClass>>>() { });

My payload class is as follows:

@Data
@EqualsAndHashCode(exclude = {"town", "direction", "type"})
@NoArgsConstructor
public class PayloadClass {
private String id;
@NonNull private Set<String> type = Collections.emptySet();
@NonNull private Set<String> direction = Collections.emptySet();
@NonNull private Set<Town> town = Collections.emptySet();

And my town class is done as so to represent a a Town has a leader and streets

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Town{

@JsonProperty(value = "leader")
private String leader;

@JsonProperty(value = "streets")
private Set<String> streets = Collections.emptySet();

The issue is in the mapping, where it tries to map the leader and Set of streets within the one object.

I am then getting the following error but not sure why:

U [main] ERROR - Cannot construct instance of ` 
com.Town` (although at least one Creator 
exists): no String-argument constructor/factory method to deserialize from String value 
('leader')
at [Source: (BufferedInputStream); line: 16, column: 9] (through reference chain: 
java.util.HashMap["PayloadClass"]->java.util.HashSet[0]- 
com.PayloadClass["town"]->java.util.HashSet[1])

I am trying to keep the JSON in this format for upstream apps, hopefully I can resolve this issue in the mapping types.

So the new field I am trying to add, is the leader field within the Json. Without this field it performs without issue.


Solution

  • Your json format is wrong. If town is an array of city objects with a leader and an array of street names, you should write in json :

    {
      "town": [
        {
          "leader": "",
          "streets" :  [
            "mainStreet"
          ]
        }
      ]
    }