6

I am working on a Java project which parses a JSON response received from an external API using the Jackson library. One of the fields in the response sometimes comes as a single object and in certain cases, it comes as an array of objects. So I'm not sure which datatype I should select to map this response back into a Java Object. How should I properly map both response types to a Java object?

In the possible duplicate mentioned above, the response is always a list but in my case its not. So I dont think its the duplicate of above issue.

Below is the response I'm receiving:

"configuration": {
    "additionalServices": {
       "type": "Standard DDOS IP Protection"
    },
}

And sometimes this is how I receive the same response:

"configuration": {
    "additionalServices": [
        {
            "type": "Standard DDOS IP Protection"
        },
        {
            "type": "Remote Management"
        }
    ],
}

This is how my Java mapping looks like now:

@JsonIgrnoreProperties(ignoreUnknown = true)
public class Configuration {
    private List<AdditionalServices> additionalServices;
}
@JsonIgrnoreProperties(ignoreUnknown = true)
public class AdditionalServices {
    private String type;
}

If I use the below declaration then it will parse only the array output and throws exception for the first response:

private List<AdditionalServices> additionalServices;

If I use the below declaration then it will parse only the first response and throws an exception for the second response:

private AdditionalServices additionalServices;

Exception in parsing the data:

Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token

Dino
  • 7,779
  • 12
  • 46
  • 85
rakesh
  • 135
  • 3
  • 15

2 Answers2

6

You can instruct Jackson to "wrap" a single value in an array by enabling the ACCEPT_SINGLE_VALUE_AS_ARRAY feature:

Feature that determines whether it is acceptable to coerce non-array (in JSON) values to work with Java collection (arrays, java.util.Collection) types.

For example:

objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

Then as long as additionalServices is a collection type, deserialisation should succeed for a single-value or array.

Jonathan
  • 20,053
  • 6
  • 63
  • 70
0

In first JSON pass like this,

"configuration": {
   "additionalServices": [{
      "type": "Standard DDOS IP Protection"
    }],
 }
Sana
  • 360
  • 3
  • 13
  • The above mentioned JSON response is from external API, so basically can't change JSON response like u did above and keep in array. – Ajay Aug 14 '19 at 09:48