Json to Java object conversion - Failing in Jackson

AshTyson :

I am trying to parse the following object using jackson in Java.

[
  [null, {
    "distance": 2272,
    "duration": 580
  }, {
    "distance": 7217,
    "duration": 1393
  }, {
    "distance": 5773,
    "duration": 1061
  }, {
    "distance": 6208,
    "duration": 1170
  }, {
    "distance": 18846,
    "duration": 2686
  }],
  [{
    "distance": 2262,
    "duration": 558
  }, null, {
    "distance": 7144,
    "duration": 1366
  }, {
    "distance": 4803,
    "duration": 801
  }, {
    "distance": 5238,
    "duration": 910
  }, {
    "distance": 17876,
    "duration": 2426
  }],
  [{
    "distance": 7207,
    "duration": 1393
  }, {
    "distance": 7505,
    "duration": 1411
  }, null, {
    "distance": 12375,
    "duration": 2010
  }, {
    "distance": 12809,
    "duration": 2119
  }, {
    "distance": 24868,
    "duration": 3462
  }],
  [{
    "distance": 7481,
    "duration": 1255
  }, {
    "distance": 4643,
    "duration": 831
  }, {
    "distance": 11497,
    "duration": 2060
  }, null, {
    "distance": 434,
    "duration": 109
  }, {
    "distance": 13197,
    "duration": 1657
  }],
  [{
    "distance": 7723,
    "duration": 1326
  }, {
    "distance": 4884,
    "duration": 902
  }, {
    "distance": 11739,
    "duration": 2130
  }, {
    "distance": 434,
    "duration": 107
  }, null, {
    "distance": 12999,
    "duration": 1628
  }],
  [{
    "distance": 20372,
    "duration": 2918
  }, {
    "distance": 17534,
    "duration": 2493
  }, {
    "distance": 25912,
    "duration": 3432
  }, {
    "distance": 13669,
    "duration": 1774
  }, {
    "distance": 13414,
    "duration": 1779
  }, null]
]

Am I'm getting the following error.

Exception in thread "main" java.lang.IllegalArgumentException: Cannot construct instance of com.beeline.DistanceMatrix (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('[[null,{"distance":2272,"duration":580},{"distance":7217,"duration":1393},{"distance":5773,"duration":1061},{"distance":6208,"duration":1170},{"distance":18846,"duration":2686}],[{"distance":2262,"duration":558},null,{"distance":7144,"duration":1366},{"distance":4803,"duration":801},{"distance":5238,"duration":910},{"distance":17876,"duration":2426}],[{"distance":7207,"duration":1393},{"distance":7505,"duration":1411},null,{"distance":12375,"duration":2010},{"distance":12809,"duration":2119},{"distance":24868,"duration":3462}],[{"distance":7481,"duration":1255},{"distance":4643,"duration":831},{"distance":11497,"duration":2060},null,{"distance":434,"duration":109},{"distance":13197,"duration":1657}],[{"distance":7723,"duration":1326},{"distance":4884,"duration":902},{"distance":11739,"duration":2130},{"distance":434,"duration":107},null,{"distance":12999,"duration":1628}],[{"distance":20372,"duration":2918},{"distance":17534,"duration":2493},{"distance":25912,"duration":3432},{"distance":13669,"duration":1774},{"distance":13414,"duration":1779},null]]') at [Source: UNKNOWN; line: -1, column: -1] at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3750) at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3668) at com.beeline.JsonParser.(JsonParser.java:17)

The classes I'm using are

JsonParser.java

public class JsonParser {
    private DistanceMatrix matrix = new DistanceMatrix();
    public JsonParser() {
        String jsonString = "[[null,{\"distance\":2272,\"duration\":580},{\"distance\":7217,\"duration\":1393},{\"distance\":5773,\"duration\":1061},{\"distance\":6208,\"duration\":1170},{\"distance\":18846,\"duration\":2686}],[{\"distance\":2262,\"duration\":558},null,{\"distance\":7144,\"duration\":1366},{\"distance\":4803,\"duration\":801},{\"distance\":5238,\"duration\":910},{\"distance\":17876,\"duration\":2426}],[{\"distance\":7207,\"duration\":1393},{\"distance\":7505,\"duration\":1411},null,{\"distance\":12375,\"duration\":2010},{\"distance\":12809,\"duration\":2119},{\"distance\":24868,\"duration\":3462}],[{\"distance\":7481,\"duration\":1255},{\"distance\":4643,\"duration\":831},{\"distance\":11497,\"duration\":2060},null,{\"distance\":434,\"duration\":109},{\"distance\":13197,\"duration\":1657}],[{\"distance\":7723,\"duration\":1326},{\"distance\":4884,\"duration\":902},{\"distance\":11739,\"duration\":2130},{\"distance\":434,\"duration\":107},null,{\"distance\":12999,\"duration\":1628}],[{\"distance\":20372,\"duration\":2918},{\"distance\":17534,\"duration\":2493},{\"distance\":25912,\"duration\":3432},{\"distance\":13669,\"duration\":1774},{\"distance\":13414,\"duration\":1779},null]]";
        ObjectMapper oMapper = new ObjectMapper();
        oMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        oMapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
        matrix = oMapper.convertValue(jsonString, DistanceMatrix.class);
        System.out.print(matrix);
    }
}

DistanceMatrix.java

public class DistanceMatrix {
    public ArrayList<ArrayList<Map<String, Float>>> matrix = new ArrayList<ArrayList<Map<String, Float>>>();
}

I saw multiple issues like this on GitHub and SO. But I can't figure out why it doesn't work. Any pointers on what is going wrong?

AshTyson :

The actual answer which worked for me is both derived from the answer given by @dnt and the same question in Google groups and some own experiment.

  1. First this line

matrix = oMapper.convertValue(jsonString, DistanceMatrix.class);

should be changed to

try {
  matrix = oMapper.readValue(jsonString, DistanceMatrix.class);
}

So this will properly read the JSON and try to match it to the structure given.

  1. Once that is done it will throw

Cannot deserialize instance of com.beeline.DistanceMatrix out of START_ARRAY token

The reason is the distance matrix class describes a JSON object. The input is expecting { "matrix" : }

  1. Thanks to comment made by @ngueno. There will be a null pointer exception if the object is null. But the library can accept null values as object value. Example

For the above class, this is accepted

[{"distance":7217,"duration":null},{"distance":null,"duration":1061}]

Whereas this is not accepted

[{"distance":7217,"duration":1393},null]

I'm pretty sure you can handle it differently in Java (I'm a beginner). But I replaced all my nulls with empty object notation {}. So empty object will create a map with no key-value pair. I'll research how to store null in Map structure. Or if anyone else comments on it I will update the answer accordingly.

Thanks for the contributions guys.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=147844&siteId=1