MainstreamDeveloper00
MainstreamDeveloper00

Reputation: 8556

Can't parse JSON array of arrays to LinkedHashMap in Jackson

I' m developing an Android REST client. We use JSON as data exchange format, so I use a Jackson parser. I get different Json responses from the server like simple arrays:

{"user_id":"332","user_role":"1"} 

or something else. All these stuff I parse to LinkedHashMap<String, Object> and everything works perfectly but when I got this response from the server:

[ { "user_id":"352",
    "user_role":"expert",
    "name":"Test 12-18",
    "description":"Test" },

  { "user_id":"263",
    "user_role":"novice lab",
    "name":"Tom's Desk",
    "description":"Desk"}
]

I got null: {} after parsing.Here is my code where i use Jackson:

 ObjectMapper mapParametersToJSON = new ObjectMapper();
 String serverResponseBody = responseFromServer.getBody();
LinkedHashMap<String, Object> resultofOperation = new LinkedHashMap<String,
     Object>();
TypeReference<LinkedHashMap<String,Object>> genericTypeReferenceInformation = new
    TypeReference<LinkedHashMap<String,Object>>() {};
    try {
     resultofOperation =  mapParametersToJSON.readValue(serverResponseBody,
         genericTypeReferenceInformation);

So, why Jackson failed to parse this? How can I fix this?

Upvotes: 2

Views: 7564

Answers (4)

StaxMan
StaxMan

Reputation: 116600

Others have suggested the problem, but solutions are bit incomplete. If you need to deal with JSON Objects and Arrays, you can either bind to java.lang.Object, check the type:

Object stuff = objectMapper.readValue(json, Object.class);

and you will get either List or Map (specifically, ArrayList or LinkedHashMap, by default; these defaults can be changed).

Or you can do JSON trees with JsonNode:

JsonNode root = objectMapper.readTree(json);
if (root.isObject()) { // JSON Object
} else if (root.isArray()) { ...
}

latter is often more convenient.

One nice thing is that you can still create regular POJOs out of these, for example:

if (root.isObject()) { MyObject ob = objectMapper.treeToValue(MyObject.class); } // or with Object, use objectMapper.convertValue(ob, MyObject.class)

so you can even have different handling for different types; go back and forth different representations.

Upvotes: 5

n1ckolas
n1ckolas

Reputation: 4450

You are facing an error, because [] construction can't be translated into Map reference, only in List or array.

I would recommend do it something in this way:

ObjectMapper objectMapper = new ObjectMapper();

List<Map<String,String>> parsedResult = objectMapper.reader(CollectionType.construct(LinkedList.class, MapType.construct(LinkedHashMap.class, SimpleType.construct(String.class), SimpleType.construct(String.class)))).readValue(serverResponseBody);

//if you need the one result map
Map<String, String> resultMap = new LinkedHashMap<String, String>();

for (Map<String, String> map: parsedResult){
    resultMap.putAll(map);
}

Upvotes: 0

pbespechnyi
pbespechnyi

Reputation: 2291

In JSON the {"key": "value"} is Object and the ["this", "that"] is Array.

So, in case when you're receiving the array of objects you should use something like List<Map<Key, Value>>.

Upvotes: 0

323go
323go

Reputation: 14274

The first JSON in your question is a map, or an object. The second is an array. You're not parsing an array, you're parsing a map.

You need to do something like this:

List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});

Almost identical question with answer here.

Upvotes: 4

Related Questions