0

I am using Java Spring with Jackson to consume JSON data from a partner's web service, and I've run into a challenge that I'm having trouble overcoming. The issue is that sometimes the data I need to consume contains a single element of a particular type and sometimes the data includes an entire list of these elements (please forgive me if I'm not using the correct JSON terms here). For example:

{
"number": "12121212",
"activity": { "status": "in transit", "date": "20100429" }
}

This contains a single "activity" element. Then in the next example, there is a list of the "activity" elements:

{
"number": "12121212",
"activity": [{ "status": "arrived", "date": "20160430" }, { "status": "in transit", "date": "20160429" }, { "status": "shipping", "date": "20160429"}]
}

I'm using com.fasterxml.jackson.databind.ObjectMapper to map the JSON to java beans, and here are my two beans:

public class Activity {
    private String status;
    private String date;

    /* getters and setters */
}

public class Message {
    private String number;
    private Activity activity;

    /* getters and setters */
}

And my calling code is this:

public static void main(String[] args) {
    Messages m = new Messages();
    String jsonMessage = getJsonMessage();      // This gets the JSON message to be run through ObjectMapper
    ObjectMapper mapper = new ObjectMapper();

    try {
        Message message = mapper.readValue(jsonMessage, Message.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
}   // end method main()

When I execute this code while receiving the JSON message with a single "activity" element, it works. When executing it with a list of "activity" elements, I get the following error:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.graybar.utilities.parsejson.Activity out of START_ARRAY token

Changing the Message bean to the following makes the code work when working with a list of "activity" elements:

public class Message {
    private String number;
    private ArrayList<Activity> activity;

    /* getters and setters */
}

However, now the code won't work with a single "activity" element. I get the following error:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

I have to imagine there's a simple way to handle single or a list of instances of an element within the Jackson framework, but unfortunately I've not been able to find it.

Any help is appreciated!

-Stephen Spalding

cchapman
  • 3,269
  • 10
  • 50
  • 68
Stephen
  • 1,977
  • 2
  • 15
  • 19
  • 1
    http://stackoverflow.com/questions/37164399/jackson-desrialize-when-jsonproperty-is-sometimes-array-and-sometimes-a-single-o/37175527#37175527 – varren May 19 '16 at 19:27

1 Answers1

1

@varren provided the link above that helped me find the solution. I added the following line of code to my calling method:

mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); 

So, the full method looks like this:

public static void main(String[] args) {
    Messages m = new Messages();
    String jsonMessage = getJsonMessage();      // This gets the JSON message to be run through ObjectMapper
    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); /* this is the fix */

    try {
        Message message = mapper.readValue(jsonMessage, Message.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
}   // end method main()
Udo Held
  • 12,314
  • 11
  • 67
  • 93
Stephen
  • 1,977
  • 2
  • 15
  • 19