I have a JSONObject
with some attributes that I want to convert into a Map<String, Object>
Is there something that I can use from the json.org or ObjectMapper
?
I have a JSONObject
with some attributes that I want to convert into a Map<String, Object>
Is there something that I can use from the json.org or ObjectMapper
?
You can use Gson() (com.google.gson) library if you find any difficulty using Jackson.
//changed yourJsonObject.toString() to yourJsonObject as suggested by Martin Meeser
HashMap<String, Object> yourHashMap = new Gson().fromJson(yourJsonObject, HashMap.class);
use Jackson (https://github.com/FasterXML/jackson) from http://json.org/
HashMap<String,Object> result =
new ObjectMapper().readValue(<JSON_OBJECT>, HashMap.class);
This is what worked for me:
public static Map<String, Object> toMap(JSONObject jsonobj) throws JSONException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keys = jsonobj.keys();
while(keys.hasNext()) {
String key = keys.next();
Object value = jsonobj.get(key);
if (value instanceof JSONArray) {
value = toList((JSONArray) value);
} else if (value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
map.put(key, value);
} return map;
}
public static List<Object> toList(JSONArray array) throws JSONException {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
if (value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if (value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
list.add(value);
} return list;
}
Most of this is from this question: How to convert JSONObject to new Map for all its keys using iterator java
The best way to convert it to HashMap<String, Object>
is this:
HashMap<String, Object> result = new ObjectMapper().readValue(jsonString, new TypeReference<Map<String, Object>>(){}));
Note to the above solution (from A Paul): The solution doesn't work, cause it doesn't reconstructs back a HashMap< String, Object > - instead it creates a HashMap< String, LinkedHashMap >.
Reason why is because during demarshalling, each Object (JSON marshalled as a LinkedHashMap) is used as-is, it takes 1-on-1 the LinkedHashMap (instead of converting the LinkedHashMap back to its proper Object).
If you had a HashMap< String, MyOwnObject > then proper demarshalling was possible - see following example:
ObjectMapper mapper = new ObjectMapper();
TypeFactory typeFactory = mapper.getTypeFactory();
MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, MyOwnObject.class);
HashMap<String, MyOwnObject> map = mapper.readValue(new StringReader(hashTable.toString()), mapType);
Found out these problems can be addressed by using
ObjectMapper#convertValue(Object fromValue, Class<T> toValueType)
As a result, the origal quuestion can be solved in a 2-step converison:
Demarshall the JSON back to an object - in which the Map<String, Object>
is demarshalled as a HashMap<String, LinkedHashMap>
, by using bjectMapper#readValue().
Convert inner LinkedHashMaps back to proper objects
ObjectMapper mapper = new ObjectMapper();
Class clazz = (Class) Class.forName(classType);
MyOwnObject value = mapper.convertValue(value, clazz);
To prevent the 'classType' has to be known in advance, I enforced during marshalling an extra Map was added, containing <key, classNameString>
pairs. So at unmarshalling time, the classType can be extracted dynamically.
I'll keep it further simple
There is an out of the box function available by name toMap()
which should do the job
JSONObject jsonObject = new JSONObject(stringAsJson);
Map<String,Object> jsonMap = jsonObject.toMap();
This is how I did it in Kotlin:
mutableMapOf<String, Any>().apply {
jsonObj.keys().forEach { put(it, jsonObj[it]) }
}
import com.alibaba.fastjson.JSONObject;
Map<String, Object> map = new HashMap<String, Object>();
JSONObject rec = JSONObject.parseObject(<JSONString>);
map.put(rec.get("code").toString(), rec.get("value").toString());