Home > Blockchain >  Java: Deserialize object with list of Objects
Java: Deserialize object with list of Objects

Time:04-14

I have this JSON: (passed as Map<String, Object>)

{
  "id": 1000,
  "lab": [
    "LAB1",
    "LAB2",
    "LAB3"
  ],
  "name": "TEST",
  "ref": {
    "id": 1000,
    "code": "REFCODE",
    "description": "REF DESC"
  },
  "employee": {
    "id": 1000,
    "name": "Emp1000",
    "tin": null,
    "active": true
  },
  "contacts": [
    {
      "id": 1000,
      "name": "Contact 1",
      "emailAddress": "[email protected]",
      "active": true,
      "positions": [
        {
          "position": {
            "id": 1000,
            "code": "POS",
            "description": "POS DESC"
          },
          "effectiveStartDate": [
            2022,
            3,
            14
          ]
        }
      ]
    }
  ],
  "status": "NEW"
}

This is my DTO and ContactDTO:

public class DTO {
    private Long id;
    ...

    @JsonProperty("contacts")
    private List<ContactDTO> contacts; 

}

@Builder
public class ContactDTO implements Serializable {    
    private Long id;
    private String name;
    private String emailAddress;
    private Boolean active;
    @NotEmpty
    private List<ContactPositionDTO> positions;
}

Here is my service class with object mapper and process method which accepts the JSON map:

private ObjectMapper objectMapper() {
    var objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    return objectMapper;
}

public void process(final Map<String, Object> map) {
    objectMapper().convertValue(map, DTO.class);
}

However, I am getting java.lang.IllegalArgumentException: Cannot deserialize value of type java.util.ArrayList

And if I add DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY I am getting a different error:

java.lang.IllegalArgumentException: Cannot construct instance of ContactDTO (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('[{id=1000, name=Contact 1, .....

CodePudding user response:

I cannot be certain given the information I have, however, this is the hotspot I see:

  "effectiveStartDate": [
    2022,
    3,
    14
  ]

It's ill formatted and a chore to work with. Look into using a real DateTime object, and parsing.

CodePudding user response:

You have two alternative options to fix your ContactDTO class:

  • Add a no-arguments constructor
    public ContactDTO() { }
    to the class. To fix the then upcoming compiler error you will need to remove the @Builder annotation.
  • Keep the @Builder annotation and add the @Jacksonized annotation to the class. This will configure the generated builder to cooperate with Jackson's deserialization. For more details see Lombok's documentation about @Jacksonized.
  • Related