Reputation: 493
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?
Upvotes: 2
Views: 5378
Reputation: 493
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.
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.
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" : }
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.
Upvotes: 0
Reputation: 113
Your DistanceMatrix
class describes a JSON object that has a key named matrix
and a corresponding value of type ArrayList<ArrayList<Map<String, Float>>>
.
You need to either wrap your JSON to look like { "matrix": <your actual JSON> }
or specify the type to convertValue
directly.
Upvotes: 3