I'm using Java, and I have a String which is JSON:
{
"name" : "abc" ,
"email id " : ["abc#gmail.com","def#gmail.com","ghi#gmail.com"]
}
Then my Map in Java:
Map<String, Object> retMap = new HashMap<String, Object>();
I want to store all the data from the JSONObject in that HashMap.
Can anyone provide code for this? I want to use the org.json library.
In recursive way:
public static Map<String, Object> jsonToMap(JSONObject json) throws JSONException {
Map<String, Object> retMap = new HashMap<String, Object>();
if(json != JSONObject.NULL) {
retMap = toMap(json);
}
return retMap;
}
public static Map<String, Object> toMap(JSONObject object) throws JSONException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keys();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.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;
}
Using Jackson library:
import com.fasterxml.jackson.databind.ObjectMapper;
Map<String, Object> mapping = new ObjectMapper().readValue(jsonStr, HashMap.class);
Using Gson, you can do the following:
Map<String, Object> retMap = new Gson().fromJson(
jsonString, new TypeToken<HashMap<String, Object>>() {}.getType()
);
Hope this will work, try this:
import com.fasterxml.jackson.databind.ObjectMapper;
Map<String, Object> response = new ObjectMapper().readValue(str, HashMap.class);
str, your JSON String
As Simple as this, if you want emailid,
String emailIds = response.get("email id").toString();
I just used Gson
HashMap<String, Object> map = new Gson().fromJson(json.toString(), HashMap.class);
Here is Vikas's code ported to JSR 353:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.json.JsonArray;
import javax.json.JsonException;
import javax.json.JsonObject;
public class JsonUtils {
public static Map<String, Object> jsonToMap(JsonObject json) {
Map<String, Object> retMap = new HashMap<String, Object>();
if(json != JsonObject.NULL) {
retMap = toMap(json);
}
return retMap;
}
public static Map<String, Object> toMap(JsonObject object) throws JsonException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keySet().iterator();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.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) {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.size(); 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;
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class JsonUtils {
public static Map<String, Object> jsonToMap(JSONObject json) {
Map<String, Object> retMap = new HashMap<String, Object>();
if(json != null) {
retMap = toMap(json);
}
return retMap;
}
public static Map<String, Object> toMap(JSONObject object) {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keySet().iterator();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.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) {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.size(); 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;
}
}
try this code :
Map<String, String> params = new HashMap<String, String>();
try
{
Iterator<?> keys = jsonObject.keys();
while (keys.hasNext())
{
String key = (String) keys.next();
String value = jsonObject.getString(key);
params.put(key, value);
}
}
catch (Exception xx)
{
xx.toString();
}
Latest Update: I have used FasterXML Jackson Databind2.12.3 to Convert JSON string to Map, Map to JSON string.
// javax.ws.rs.core.Response clientresponse = null; // Read JSON with Jersey 2.0 (JAX-RS 2.0)
// String json_string = clientresponse.readEntity(String.class);
String json_string = "[\r\n"
+ "{\"domain\":\"stackoverflow.com\", \"userId\":5081877, \"userName\":\"Yash\"},\r\n"
+ "{\"domain\":\"stackoverflow.com\", \"userId\":6575754, \"userName\":\"Yash\"}\r\n"
+ "]";
System.out.println("Input/Response JSON string:"+json_string);
ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
//java.util.Map<String, String> map = mapper.readValue(json_string, java.util.Map.class);
List<Map<String, Object>> listOfMaps = mapper.readValue(json_string, new com.fasterxml.jackson.core.type.TypeReference< List<Map<String, Object>>>() {});
System.out.println("fasterxml JSON string to List of Map:"+listOfMaps);
String json = mapper.writeValueAsString(listOfMaps);
System.out.println("fasterxml List of Map to JSON string:[compact-print]"+json);
json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(listOfMaps);
System.out.println("fasterxml List of Map to JSON string:[pretty-print]"+json);
output:
Input/Response JSON string:[
{"domain":"stackoverflow.com", "userId":5081877, "userName":"Yash"},
{"domain":"stackoverflow.com", "userId":6575754, "userName":"Yash"}
]
fasterxml JSON string to List of Map:[{domain=stackoverflow.com, userId=5081877, userName=Yash}, {domain=stackoverflow.com, userId=6575754, userName=Yash}]
fasterxml List of Map to JSON string:[compact-print][{"domain":"stackoverflow.com","userId":5081877,"userName":"Yash"},{"domain":"stackoverflow.com","userId":6575754,"userName":"Yash"}]
fasterxml List of Map to JSON string:[pretty-print][ {
"domain" : "stackoverflow.com",
"userId" : 5081877,
"userName" : "Yash"
}, {
"domain" : "stackoverflow.com",
"userId" : 6575754,
"userName" : "Yash"
} ]
Converting a JSON String to Map
public static java.util.Map<String, Object> jsonString2Map( String jsonString ) throws org.json.JSONException {
Map<String, Object> keys = new HashMap<String, Object>();
org.json.JSONObject jsonObject = new org.json.JSONObject( jsonString ); // HashMap
java.util.Iterator<?> keyset = jsonObject.keys(); // HM
while (keyset.hasNext()) {
String key = (String) keyset.next();
Object value = jsonObject.get(key);
System.out.print("\n Key : "+key);
if ( value instanceof org.json.JSONObject ) {
System.out.println("Incomin value is of JSONObject : ");
keys.put( key, jsonString2Map( value.toString() ));
} else if ( value instanceof org.json.JSONArray) {
org.json.JSONArray jsonArray = jsonObject.getJSONArray(key);
//JSONArray jsonArray = new JSONArray(value.toString());
keys.put( key, jsonArray2List( jsonArray ));
} else {
keyNode( value);
keys.put( key, value );
}
}
return keys;
}
Converting JSON Array to List
public static java.util.List<Object> jsonArray2List( org.json.JSONArray arrayOFKeys ) throws org.json.JSONException {
System.out.println("Incoming value is of JSONArray : =========");
java.util.List<Object> array2List = new java.util.ArrayList<Object>();
for ( int i = 0; i < arrayOFKeys.length(); i++ ) {
if ( arrayOFKeys.opt(i) instanceof org.json.JSONObject ) {
Map<String, Object> subObj2Map = jsonString2Map(arrayOFKeys.opt(i).toString());
array2List.add(subObj2Map);
} else if ( arrayOFKeys.opt(i) instanceof org.json.JSONArray ) {
java.util.List<Object> subarray2List = jsonArray2List((org.json.JSONArray) arrayOFKeys.opt(i));
array2List.add(subarray2List);
} else {
keyNode( arrayOFKeys.opt(i) );
array2List.add( arrayOFKeys.opt(i) );
}
}
return array2List;
}
public static Object keyNode(Object o) {
if (o instanceof String || o instanceof Character) return (String) o;
else if (o instanceof Number) return (Number) o;
else return o;
}
Display JSON of Any Format
public static void displayJSONMAP( Map<String, Object> allKeys ) throws Exception{
Set<String> keyset = allKeys.keySet(); // HM$keyset
if (! keyset.isEmpty()) {
Iterator<String> keys = keyset.iterator(); // HM$keysIterator
while (keys.hasNext()) {
String key = keys.next();
Object value = allKeys.get( key );
if ( value instanceof Map ) {
System.out.println("\n Object Key : "+key);
displayJSONMAP(jsonString2Map(value.toString()));
}else if ( value instanceof List ) {
System.out.println("\n Array Key : "+key);
JSONArray jsonArray = new JSONArray(value.toString());
jsonArray2List(jsonArray);
}else {
System.out.println("key : "+key+" value : "+value);
}
}
}
}
Google.gson to HashMap.
Convert using Jackson :
JSONObject obj = new JSONObject().put("abc", "pqr").put("xyz", 5);
Map<String, Object> map = new ObjectMapper().readValue(obj.toString(), new TypeReference<Map<String, Object>>() {});
You can convert any JSON to map by using Jackson library as below:
String json = "{\r\n\"name\" : \"abc\" ,\r\n\"email id \" : [\"abc#gmail.com\",\"def#gmail.com\",\"ghi#gmail.com\"]\r\n}";
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<String, Object>();
// convert JSON string to Map
map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
System.out.println(map);
Maven Dependencies for Jackson :
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
<scope>compile</scope>
</dependency>
Hope this will help. Happy coding :)
You can use Jackson API as well for this :
final String json = "....your json...";
final ObjectMapper mapper = new ObjectMapper();
final MapType type = mapper.getTypeFactory().constructMapType(
Map.class, String.class, Object.class);
final Map<String, Object> data = mapper.readValue(json, type);
If you hate recursion - using a Stack and javax.json to convert a Json String into a List of Maps:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import javax.json.Json;
import javax.json.stream.JsonParser;
public class TestCreateObjFromJson {
public static List<Map<String,Object>> extract(InputStream is) {
List extracted = new ArrayList<>();
JsonParser parser = Json.createParser(is);
String nextKey = "";
Object nextval = "";
Stack s = new Stack<>();
while(parser.hasNext()) {
JsonParser.Event event = parser.next();
switch(event) {
case START_ARRAY : List nextList = new ArrayList<>();
if(!s.empty()) {
// If this is not the root object, add it to tbe parent object
setValue(s,nextKey,nextList);
}
s.push(nextList);
break;
case START_OBJECT : Map<String,Object> nextMap = new HashMap<>();
if(!s.empty()) {
// If this is not the root object, add it to tbe parent object
setValue(s,nextKey,nextMap);
}
s.push(nextMap);
break;
case KEY_NAME : nextKey = parser.getString();
break;
case VALUE_STRING : setValue(s,nextKey,parser.getString());
break;
case VALUE_NUMBER : setValue(s,nextKey,parser.getLong());
break;
case VALUE_TRUE : setValue(s,nextKey,true);
break;
case VALUE_FALSE : setValue(s,nextKey,false);
break;
case VALUE_NULL : setValue(s,nextKey,"");
break;
case END_OBJECT :
case END_ARRAY : if(s.size() > 1) {
// If this is not a root object, move up
s.pop();
} else {
// If this is a root object, add ir ro rhw final
extracted.add(s.pop());
}
default : break;
}
}
return extracted;
}
private static void setValue(Stack s, String nextKey, Object v) {
if(Map.class.isAssignableFrom(s.peek().getClass()) ) ((Map)s.peek()).put(nextKey, v);
else ((List)s.peek()).add(v);
}
}
There’s an older answer using javax.json posted here, however it only converts JsonArray and JsonObject, but there are still JsonString, JsonNumber, and JsonValue wrapper classes in the output. If you want to get rid of these, here’s my solution which will unwrap everything.
Beside that, it makes use of Java 8 streams and is contained in a single method.
/**
* Convert a JsonValue into a “plain” Java structure (using Map and List).
*
* #param value The JsonValue, not <code>null</code>.
* #return Map, List, String, Number, Boolean, or <code>null</code>.
*/
public static Object toObject(JsonValue value) {
Objects.requireNonNull(value, "value was null");
switch (value.getValueType()) {
case ARRAY:
return ((JsonArray) value)
.stream()
.map(JsonUtils::toObject)
.collect(Collectors.toList());
case OBJECT:
return ((JsonObject) value)
.entrySet()
.stream()
.collect(Collectors.toMap(
Entry::getKey,
e -> toObject(e.getValue())));
case STRING:
return ((JsonString) value).getString();
case NUMBER:
return ((JsonNumber) value).numberValue();
case TRUE:
return Boolean.TRUE;
case FALSE:
return Boolean.FALSE;
case NULL:
return null;
default:
throw new IllegalArgumentException("Unexpected type: " + value.getValueType());
}
}
You can use google gson library to convert json object.
https://code.google.com/p/google-gson/
Other librarys like Jackson are also available.
This won't convert it to a map. But you can do all things which you want.
Brief and Useful:
/**
* #param jsonThing can be a <code>JsonObject</code>, a <code>JsonArray</code>,
* a <code>Boolean</code>, a <code>Number</code>,
* a <code>null</code> or a <code>JSONObject.NULL</code>.
* #return <i>Appropriate Java Object</i>, that may be a <code>Map</code>, a <code>List</code>,
* a <code>Boolean</code>, a <code>Number</code> or a <code>null</code>.
*/
public static Object jsonThingToAppropriateJavaObject(Object jsonThing) throws JSONException {
if (jsonThing instanceof JSONArray) {
final ArrayList<Object> list = new ArrayList<>();
final JSONArray jsonArray = (JSONArray) jsonThing;
final int l = jsonArray.length();
for (int i = 0; i < l; ++i) list.add(jsonThingToAppropriateJavaObject(jsonArray.get(i)));
return list;
}
if (jsonThing instanceof JSONObject) {
final HashMap<String, Object> map = new HashMap<>();
final Iterator<String> keysItr = ((JSONObject) jsonThing).keys();
while (keysItr.hasNext()) {
final String key = keysItr.next();
map.put(key, jsonThingToAppropriateJavaObject(((JSONObject) jsonThing).get(key)));
}
return map;
}
if (JSONObject.NULL.equals(jsonThing)) return null;
return jsonThing;
}
Thank #Vikas Gupta.
The following parser reads a file, parses it into a generic JsonElement, using Google's JsonParser.parse method, and then converts all the items in the generated JSON into a native Java List<object> or Map<String, Object>.
Note: The code below is based off of Vikas Gupta's answer.
GsonParser.java
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
public class GsonParser {
public static void main(String[] args) {
try {
print(loadJsonArray("data_array.json", true));
print(loadJsonObject("data_object.json", true));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void print(Object object) {
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(object).toString());
}
public static Map<String, Object> loadJsonObject(String filename, boolean isResource)
throws UnsupportedEncodingException, FileNotFoundException, JsonIOException, JsonSyntaxException, MalformedURLException {
return jsonToMap(loadJson(filename, isResource).getAsJsonObject());
}
public static List<Object> loadJsonArray(String filename, boolean isResource)
throws UnsupportedEncodingException, FileNotFoundException, JsonIOException, JsonSyntaxException, MalformedURLException {
return jsonToList(loadJson(filename, isResource).getAsJsonArray());
}
private static JsonElement loadJson(String filename, boolean isResource) throws UnsupportedEncodingException, FileNotFoundException, JsonIOException, JsonSyntaxException, MalformedURLException {
return new JsonParser().parse(new InputStreamReader(FileLoader.openInputStream(filename, isResource), "UTF-8"));
}
public static Object parse(JsonElement json) {
if (json.isJsonObject()) {
return jsonToMap((JsonObject) json);
} else if (json.isJsonArray()) {
return jsonToList((JsonArray) json);
}
return null;
}
public static Map<String, Object> jsonToMap(JsonObject jsonObject) {
if (jsonObject.isJsonNull()) {
return new HashMap<String, Object>();
}
return toMap(jsonObject);
}
public static List<Object> jsonToList(JsonArray jsonArray) {
if (jsonArray.isJsonNull()) {
return new ArrayList<Object>();
}
return toList(jsonArray);
}
private static final Map<String, Object> toMap(JsonObject object) {
Map<String, Object> map = new HashMap<String, Object>();
for (Entry<String, JsonElement> pair : object.entrySet()) {
map.put(pair.getKey(), toValue(pair.getValue()));
}
return map;
}
private static final List<Object> toList(JsonArray array) {
List<Object> list = new ArrayList<Object>();
for (JsonElement element : array) {
list.add(toValue(element));
}
return list;
}
private static final Object toPrimitive(JsonPrimitive value) {
if (value.isBoolean()) {
return value.getAsBoolean();
} else if (value.isString()) {
return value.getAsString();
} else if (value.isNumber()){
return value.getAsNumber();
}
return null;
}
private static final Object toValue(JsonElement value) {
if (value.isJsonNull()) {
return null;
} else if (value.isJsonArray()) {
return toList((JsonArray) value);
} else if (value.isJsonObject()) {
return toMap((JsonObject) value);
} else if (value.isJsonPrimitive()) {
return toPrimitive((JsonPrimitive) value);
}
return null;
}
}
FileLoader.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class FileLoader {
public static Reader openReader(String filename, boolean isResource) throws UnsupportedEncodingException, FileNotFoundException, MalformedURLException {
return openReader(filename, isResource, "UTF-8");
}
public static Reader openReader(String filename, boolean isResource, String charset) throws UnsupportedEncodingException, FileNotFoundException, MalformedURLException {
return new InputStreamReader(openInputStream(filename, isResource), charset);
}
public static InputStream openInputStream(String filename, boolean isResource) throws FileNotFoundException, MalformedURLException {
if (isResource) {
return FileLoader.class.getClassLoader().getResourceAsStream(filename);
}
return new FileInputStream(load(filename, isResource));
}
public static String read(String path, boolean isResource) throws IOException {
return read(path, isResource, "UTF-8");
}
public static String read(String path, boolean isResource, String charset) throws IOException {
return read(pathToUrl(path, isResource), charset);
}
#SuppressWarnings("resource")
protected static String read(URL url, String charset) throws IOException {
return new Scanner(url.openStream(), charset).useDelimiter("\\A").next();
}
protected static File load(String path, boolean isResource) throws MalformedURLException {
return load(pathToUrl(path, isResource));
}
protected static File load(URL url) {
try {
return new File(url.toURI());
} catch (URISyntaxException e) {
return new File(url.getPath());
}
}
private static final URL pathToUrl(String path, boolean isResource) throws MalformedURLException {
if (isResource) {
return FileLoader.class.getClassLoader().getResource(path);
}
return new URL("file:/" + path);
}
}
If you want no-lib version, here is the solution with regex:
public static HashMap<String, String> jsonStringToMap(String inputJsonString) {
final String regex = "(?:\\\"|\\')(?<key>[\\w\\d]+)(?:\\\"|\\')(?:\\:\\s*)(?:\\\"|\\')?(?<value>[\\w\\s-]*)(?:\\\"|\\')?";
HashMap<String, String> map = new HashMap<>();
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(inputJsonString);
while (matcher.find()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
map.put(matcher.group("key"), matcher.group("value"));
}
}
return map;
}
Imagine u have a list of email like below. not constrained to any programming language,
emailsList = ["abc#gmail.com","def#gmail.com","ghi#gmail.com"]
Now following is JAVA code - for converting json to map
JSONObject jsonObj = new JSONObject().put("name","abc").put("email id",emailsList);
Map<String, Object> s = jsonObj.getMap();
This is an old question and maybe still relate to someone.
Let's say you have string HashMap hash and JsonObject jsonObject.
1) Define key-list.
Example:
ArrayList<String> keyArrayList = new ArrayList<>();
keyArrayList.add("key0");
keyArrayList.add("key1");
2) Create foreach loop, add hash from jsonObject with:
for(String key : keyArrayList){
hash.put(key, jsonObject.getString(key));
}
That's my approach, hope it answer the question.
Using json-simple you can convert data JSON to Map and Map to JSON.
try
{
JSONObject obj11 = new JSONObject();
obj11.put(1, "Kishan");
obj11.put(2, "Radhesh");
obj11.put(3, "Sonal");
obj11.put(4, "Madhu");
Map map = new HashMap();
obj11.toJSONString();
map = obj11;
System.out.println(map.get(1));
JSONObject obj12 = new JSONObject();
obj12 = (JSONObject) map;
System.out.println(obj12.get(1));
}
catch(Exception e)
{
System.err.println("EROR : 01 :"+e);
}
Related
I have a JSON File with a nested and complex structure. I want to Flatten the data and insert it into MongoDB. The Condition is to insert only those JSON objects where the value of the "component" key is not "containers/EmptyContainer.vue". This is applicable for all JSONObjects including the root and the nested.
I have tried several methods but getting errors, one of them is this,
package jsonflattener;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.apache.activemq.artemis.utils.json.JSONArray;
import org.apache.activemq.artemis.utils.json.JSONException;
import org.apache.activemq.artemis.utils.json.JSONObject;
import org.bson.Document;
import java.util.Iterator;
public class JSONFlattenerV2 {
private static MongoCollection<Document> collection;
public JSONFlattenerV2(String databaseName, String collectionName) {
// Connect to MongoDB
try (MongoClient mongoClient = new MongoClient()) {
MongoDatabase database = mongoClient.getDatabase(databaseName);
collection = database.getCollection(collectionName);
}
}
public void processNestedJsonRecursive(Object data, Document doc) throws JSONException {
if (data instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) data;
if (jsonObject.has("component") && !"containers/EmptyContainer.vue".equals(jsonObject.getString("component"))) {
Iterator<?> it = jsonObject.keys();
while (it.hasNext()) {
String key = (String) it.next();
Object value = jsonObject.get(key);
if (value instanceof JSONObject || value instanceof JSONArray) {
processNestedJsonRecursive(value, doc);
} else {
doc.put(key, value);
}
}
collection.insertOne(doc);
return;
}
Iterator<?> it = jsonObject.keys();
while (it.hasNext()) {
String key = (String) it.next();
Object value = jsonObject.get(key);
if (value instanceof JSONObject || value instanceof JSONArray) {
processNestedJsonRecursive(value, doc);
} else {
doc.put(key, value);
}
}
collection.insertOne(doc);
} else if (data instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) data;
for (int i = 0; i < jsonArray.length(); i++) {
Object value = jsonArray.get(i);
processNestedJsonRecursive(value, doc);
}
}
}
}
Calling the method via this,
public class Test2 {
public static void main(String[] args) throws IOException, JSONException {
JSONFlattenerV2 jsonFlattener = new JSONFlattenerV2("demoDatabase", "demoCollection");
File filePath = new File("C:\\Users\\susho\\Downloads\\transparency.json");
String jsonData = new String(Files.readAllBytes(filePath.toPath()));
JSONObject jsonObject = new JSONObject(jsonData);
Document document = new Document();
jsonFlattener.processNestedJsonRecursive(jsonObject, document);
System.out.println("Populated..");
}
}
But getting these errors,
Exception in thread "main" java.lang.IllegalStateException: state should be: open
at com.mongodb.assertions.Assertions.isTrue(Assertions.java:72)
at com.mongodb.internal.connection.BaseCluster.getDescription(BaseCluster.java:167)
at com.mongodb.internal.connection.SingleServerCluster.getDescription(SingleServerCluster.java:41)
at com.mongodb.client.internal.MongoClientDelegate.getConnectedClusterDescription(MongoClientDelegate.java:155)
at com.mongodb.client.internal.MongoClientDelegate.createClientSession(MongoClientDelegate.java:105)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.getClientSession(MongoClientDelegate.java:287)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:211)
at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1053)
at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:503)
at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:487)
at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:481)
at jsonflattener.JSONFlattener.processNestedJsonRecursive(JSONFlattener.java:190)
at jsonflattener.JSONFlattener.processNestedJsonRecursive(JSONFlattener.java:208)
at jsonflattener.JSONFlattener.processNestedJsonRecursive(JSONFlattener.java:198)
at jsonflattener.JSONFlattener.processNestedJsonRecursive(JSONFlattener.java:198)
at jsonflattener.Test2.main(Test2.java:31)
Can anyone suggest what will be the correct code or what is wrong with my code?
I am trying to write a generic code were a JSON array as below example can be converted to a map .
This is sample .
where parent element is menu
{"menu": {
"items": [
{"id": "Open"},
{"id": "OpenNew", "label": "Open New"},
{"id": "ZoomIn", "label": "Zoom In"},
{"id": "ZoomOut", "label": "Zoom Out"},
{"id": "Quality"},
{"id": "Pause"}
]
}}
to map having map values as :
menu.items_0.id=open
menu.items_1.id=OpenNew
menu.items_1.label=Open New
menu.items_2.id=ZoomIn
menu.items_2.label=Zoom In
menu.items_3.id=ZoomOut
menu.items_3.id=Zoom Out
menu.items_4.id=Quality
menu.items_5.id=Pause
For my answer you need these classes:
org.json.JSONArray;
org.json.JSONException;
org.json.JSONObject;
And I'm assuming a class like this:
public class menu{
private String id;
private String label;
}
To parse - I'm ignoring if it's a stream, file, etc -. However, it assumes you've manipulated your source to create a single long String object called myString.
JSONObject topLevel = new JSONObject( myString );
JSONObject itemsArray= topLevel.getJSONArray("items");
int tempID;
String tempLabel;
//Now go through all items in array.
for(int i =0; i < itemsArray.length(); i++){
tempID = itemsArray.getJSONObject(i).getString("id");
if(itemsArray.getJSONObject(i).has("label"))
tempLabel = itemsArray.getJSONObject(i).getString("label");
else
tempLabel = null;
//whatever action you need to take
menu = new menu( tempId, tempLabel);
}
This code here gets the job done. You can extract some methods, or refactor it a little, but it should do the trick.
public class Example {
public static void main(String[] args) {
String source = "{\"menu\": {\"items\": [{\"id\": \"Open\"},{\"id\": \"OpenNew\", \"label\": \"Open New\"}, " +
"{\"id\": \"ZoomIn\", \"label\": \"Zoom In\"},"
+ "{\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"},{\"id\": \"Quality\"},{\"id\": \"Pause\"}"
+ "]}}";
JSONObject jsonObject = new JSONObject(source);
Map<String, Object> map = jsonObject.toMap();
Map<String, String> resultMap = new HashMap<>();
map
.entrySet()
.forEach(entry -> addToResult(entry, resultMap, "", ""));
System.out.println(resultMap);
}
private static void addToResult(Map.Entry<String, Object> entry, Map<String, String> resultMap, String fieldNameAcummulator, String index) {
Object value = entry.getValue();
if (!Map.class.isAssignableFrom(value.getClass()) && !List.class.isAssignableFrom(value.getClass())) {
resultMap.put(addToAccumulator(entry, fieldNameAcummulator, index), (String) value);
return;
}
if (Map.class.isAssignableFrom(value.getClass())) {
Map<String, Object> nestedMap = (HashMap<String, Object>) value;
nestedMap
.entrySet()
.forEach(nestedEntry -> addToResult(nestedEntry, resultMap, addToAccumulator(entry, fieldNameAcummulator, index), ""));
} else {
List<HashMap<String, Object>> hashMaps = (List<HashMap<String, Object>>) value;
IntStream.range(0, hashMaps.size())
.forEach(listIndex -> {
HashMap<String, Object> nestedMap = hashMaps.get(listIndex);
nestedMap.entrySet().forEach(nestedEntry -> addToResult(nestedEntry, resultMap, addToAccumulator(entry, fieldNameAcummulator, index), String.valueOf(listIndex)));
});
}
}
private static String addToAccumulator(Map.Entry<String, Object> entry, String fieldNameAcummulator, String index) {
return fieldNameAcummulator.isEmpty()
? entry.getKey()
: fieldNameAcummulator + getKeyValueWithIndex(entry, index);
}
private static String getKeyValueWithIndex(Map.Entry<String, Object> entry, String index) {
return index.isEmpty()
? ".".concat(entry.getKey())
: "_".concat(index).concat(".").concat(entry.getKey());
}
}
Feel free to ask if you have any questions regarding the implementation.
Hope it helps!
I have change some logic and it works fine after that.
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONObject;
public class JsonToMapConvertor {
private static HashMap<String, Object> mapReturn = new HashMap<String, Object>();
public static JsonParser parser = new JsonParser();
public static void main(String[] args) throws Exception{
String json ="{\n" +
" \"glossary\": {\n" +
" \"title\": \"example glossary\",\n" +
" \"GlossDiv\": {\n" +
" \"title\": \"S\",\n" +
" \"GlossList\": {\n" +
" \"GlossEntry\": {\n" +
" \"ID\": \"SGML\",\n" +
" \"SortAs\": \"SGML\",\n" +
" \"GlossTerm\": \"Standard Generalized Markup Language\",\n" +
" \"Acronym\": \"SGML\",\n" +
" \"Abbrev\": \"ISO 8879:1986\",\n" +
" \"GlossDef\": {\n" +
" \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n" +
" \"GlossSeeAlso\": [\"GML\", \"XML\"]\n" +
" },\n" +
" \"GlossSee\": \"markup\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
HashMap<String, Object> map = createHashMapFromJsonString(json,"");
System.out.println("map size "+map.size());
for (Map.Entry<String, Object> entry : map.entrySet()) {
if(!entry.getValue().toString().contains("{"))
System.out.println(entry.getKey()+" : "+entry.getValue());
}
}
public static HashMap<String, Object> createHashMapFromJsonString(String json,String prefix) throws Exception{
if(json.startsWith("[",0)){
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++){
JSONObject jsonobject = jsonArray.getJSONObject(i);
createHashMapFromJsonString(jsonobject.toString(), prefix+"_"+i);
}
}
else{
JsonObject object = (JsonObject) parser.parse(json);
Set<Map.Entry<String, JsonElement>> set = object.entrySet();
Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<String, JsonElement> entry = iterator.next();
String key = entry.getKey();
if(prefix.length()!=0){
key = prefix + "."+key;
}
JsonElement value = entry.getValue();
if (null != value) {
if (!value.isJsonPrimitive()) {
if (value.isJsonObject()) {
mapReturn.put(key, createHashMapFromJsonString(value.toString(),key));
} else if (value.isJsonArray() && value.toString().contains(":")) {
List<HashMap<String, Object>> list = new ArrayList<>();
JsonArray array = value.getAsJsonArray();
if (null != array) {
for (JsonElement element : array) {
if (!element.isJsonPrimitive()) {
createHashMapFromJsonString(value.toString(),key);
}else{
list.add(createHashMapFromJsonString(value.toString(),key));
}
}
mapReturn.put(key, list);
}
} else if (value.isJsonArray() && !value.toString().contains(":")) {
mapReturn.put(key, value.getAsJsonArray());
}
} else {
mapReturn.put(key, value.getAsString());
}
}
}
}
return mapReturn;
}
}
Just another way of converting JSONObject as List of Map as Generic
public static List<Map<String, Object>> getJsonNode(String jsonContents, String nodeName)
throws JsonProcessingException, IOException, ParseException {
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(jsonContents);
Object o = json.get(nodeName);
List<Map<String, Object>> results = Lists.newArrayList();
if (o instanceof JSONObject) {
results.add((Map<String, Object>) o);
} else if (o instanceof JSONArray) {
List<Map<String, Object>> hashMaps = (List<Map<String, Object>>) o;
results.addAll((Collection<? extends Map<String, Object>>) hashMaps);
}
return results;
}
/**
* Driver
*
* #param args
* #throws IOException
* #throws ParseException
*/
public static void main(String[] args) throws IOException, ParseException {
String jsonInputFile = "temp/input.json";
String jsonContents = new String(Files.readAllBytes(Paths.get(jsonInputFile)));
List<Map<String, Object>> results = getJsonNode(jsonContents, "summary");
for (Map<String, Object> entry : results) {
System.out.println(entry);
}
///////////////////////////////////////
results = getJsonNode(jsonContents, "payWay");
for (Map<String, Object> entry : results) {
System.out.println(entry);
}
///////////////////////////////////////
results = getJsonNode(jsonContents, "sellerDetails");
for (Map<String, Object> entry : results) {
System.out.println(entry);
}
}
I am trying to write a generic code for nested JsonObject to map conversion.
I have a sample JSONObject as
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized \n Markup Language",
"GlossDef": {
"para": "A DocBook.",
"GlossSeeAlso": [
"GML",
"XML"
]
},
"GlossSee": "markup"
}
}
}
}
}
I want to convert it into map having key value as
glossary.title = "example glossary",
glossary.GlossDiv.title = "S",
glossary.GlossDiv.GlossList.GlossEntry.ID ="SGML",
glossary.GlossDiv.GlossList.GlossEntry.SortAs ="SGML",
glossary.GlossDiv.GlossList.GlossEntry.GlossTerm="Standard Generalized
Markup Language",
glosary.GlossDiv.GlossList.GlossEntry.GlossDef.para ="A DocBook.",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso_0 = "GML",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso_1 = "XML",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSee = "markup"
This is method to read Map from json string using Jackson:
public final class JsonUtils {
public static <T> Map<String, T> readMap(String json) throws Exception {
if (json == null)
return null;
ObjectReader reader = new ObjectMapper().readerFor(Map.class);
MappingIterator<Map<String, T>> it = reader.readValues(json);
if (it.hasNextValue()) {
Map<String, T> res = it.next();
return res.isEmpty() ? Collections.emptyMap() : res;
}
return Collections.emptyMap();
}
}
This is how to read Map from json using given utilit method:
Map<String, String> map = flatMap(new LinkedHashMap<>(), "", JsonUtils.readMap(json));
And finally, this is how to transfrom Map into required Map (probably this could be done within Jackson engine, with provided custom deserializers or so, but I do not know exactly how, and thats why it is easier to me to implement it manually):
public static Map<String, String> flatMap(Map<String, String> res, String prefix, Map<String, Object> map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = prefix + entry.getKey();
Object value = entry.getValue();
if (value instanceof Map)
flatMap(res, key + '.', (Map<String, Object>)value);
else
res.put(key, String.valueOf(value));
}
return res;
}
Jackson JSON is a pretty cool library which does this for you. I wrote a quick example below but you should be able to apply this to your JSONObject.
Let's say you have A.class with property B.class who in turn has a nested property C.class
#JsonPropertyOrder({ "b" })
class A {
#JsonProperty("b")
public B b;
#JsonProperty("b")
public B getB() {
return b;
}
#JsonProperty("b")
public void setB(B b) {
this.b = b;
}
}
#JsonPropertyOrder({ "c" })
class B {
#JsonProperty("c")
public C c;
#JsonProperty("c")
public C getC() {
return c;
}
#JsonProperty("c")
public void setC(C c) {
this.c = c;
}
}
#JsonPropertyOrder({ "d" })
class C {
#JsonProperty("d")
public String d;
#JsonProperty("d")
public String getD() {
return d;
}
#JsonProperty("d")
public void setD(String d) {
this.d = d;
}
}
You can convert a nested JSONObject {"b":{"c":{"d":"test"}}} into A.class like this:
C c = new C();
c.setD("test");
B b = new B();
b.setC(c);
JSONObject obj = new JSONObject();
obj.put("b", b);
String jsonAsString = new Gson().toJson(obj);
A a = mapper.readValue(jsonAsString, A.class);
Similarly you should be able to convert your JSONObject into any type you want. Hope this helps
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JsonToMapConvertor {
private static HashMap<String, Object> mapReturn = new HashMap<String, Object>();
public static JsonParser parser = new JsonParser();
public static void main(String[] args) throws Exception{
String json ="add your Json";
HashMap<String, Object> map = createHashMapFromJsonString(json,"");
for (Map.Entry<String, Object> entry : map.entrySet()) {
if(!entry.getValue().toString().contains("{"))
System.out.println(entry.getKey()+" : "+entry.getValue());
}
}
public static HashMap<String, Object> createHashMapFromJsonString(String json,String prefix) {
JsonObject object = (JsonObject) parser.parse(json);
Set<Map.Entry<String, JsonElement>> set = object.entrySet();
Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<String, JsonElement> entry = iterator.next();
String key = entry.getKey();
if(prefix.length()!=0){
key = prefix + "."+key;
}
JsonElement value = entry.getValue();
if (null != value) {
if (!value.isJsonPrimitive()) {
if (value.isJsonObject()) {
mapReturn.put(key,value);
mapReturn.put(key, createHashMapFromJsonString(value.toString(),key));
} else if (value.isJsonArray() && value.toString().contains(":")) {
List<HashMap<String, Object>> list = new ArrayList<>();
JsonArray array = value.getAsJsonArray();
if (null != array) {
for (JsonElement element : array) {
list.add(createHashMapFromJsonString(value.toString(),key));
}
mapReturn.put(key, list);
}
} else if (value.isJsonArray() && !value.toString().contains(":")) {
mapReturn.put(key, value.getAsJsonArray());
}
} else {
mapReturn.put(key, value.getAsString());
}
}
}
return mapReturn;
}
}
What's the best way to deserialize this Json object?
{
"key1" : "val1",
"key2" : "blank"
}
into a java hashmap, where the string blank is replaced with null?
{
"key1" : "val1",
"key2" : null
}
I am currently using Jackson for deserialization.
You will find part of the answer here.
You just need to manipulate the line inside the while loop:
Object value;
if (object.get(key).equals("blank")) {
value = "null";
} else {
value = object.get(key);
}
and make print out will give:
System.out.println(map.get("key1")); // returns val1
System.out.println(map.get("key2")); // returns null
You final code will look like this, and you might need to import the proper .jar files:
import com.orsoncharts.util.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.toList;
public class JsonAnswerOne {
public static void main(String[] args) throws JSONException {
String input = "{\n" +
" \"key1\" : \"val1\",\n" +
" \"key2\" : \"blank\"\n" +
"}";
parse(input);
}
private static void parse(String input) throws JSONException {
JSONObject mainObject = new JSONObject(input);
Map<String, Object> map = jsonToMap(mainObject);
System.out.println(map.get("key1")); // returns val1
System.out.println(map.get("key2")); // returns null
}
private static Map<String, Object> jsonToMap(JSONObject json) throws JSONException {
Map<String, Object> retMap = new HashMap<String, Object>();
if (json != JSONObject.NULL) {
retMap = toMap(json);
}
return retMap;
}
private static Map<String, Object> toMap(JSONObject object) throws JSONException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keys();
while (keysItr.hasNext()) {
String key = keysItr.next();
Object value;
if (object.get(key).equals("blank")) {
value = "null";
} else {
value = object.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;
}
}
I tried this and ended up with this:
// use of the deserializer
String json = "{\"key1\":\"val1\",\"key2\":\"blank\"}";
ObjectMapper mapperMap = new ObjectMapper();
SimpleModule moduleMap = new SimpleModule();
moduleMap.addDeserializer(Map.class, new MapDeserializer());
mapperMap.registerModule(moduleMap);
Map map = mapperMap.readValue(json, Map.class);
// custom deserializer
public class MapDeserializer extends StdDeserializer<Map<String, String>> {
public MapDeserializer() {
this(null);
}
public MapDeserializer(Class<?> vc) {
super(vc);
}
#Override
public Map<String, String> deserialize(JsonParser jp, DeserializationContext context)
throws IOException {
// definitely not the best way but it works...
Map<String, String> map = new HashMap<>();
String[] keys = new String[] {"key1", "key2"};
JsonNode node = jp.getCodec().readTree(jp);
String value;
for (String key : keys) {
value = node.get(key).asText();
if (value.equals("blank")) {
value = null;
}
map.put(key, value);
}
return map;
}
}
Full example solution with an additional example to deserialize the JSON into another class:
https://gist.github.com/audacus/e70ce0f3cd4b17197d911769e05b237e
There are quite a few questions raised to convert json to HashMap.
I hope it helps everybody.
The following code will convert the direct values or Array of values, into a HashMap.
// Function called recursively
private static Map getMap(JSONObject object, String json) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
Object jsonObject = null;
Iterator<String> keys = object.keys();
while (keys.hasNext()) {
String key = keys.next();
Object value = object.get(key);
if (value instanceof JSONObject) {
map.put(key, getMap((JSONObject) value, json));
continue;
}
// If value is in the form of array
if (value instanceof JSONArray) {
JSONArray array = ((JSONArray) value);
List list = new ArrayList();
for (int i = 0 ; i < array.length() ; i++) {
jsonObject = array.get(i);
if (jsonObject instanceof JSONObject) {
list.add(getMap((JSONObject) jsonObject, json));
} else {
list.add(jsonObject);
}
}
map.put(key, list);
continue;
}
map.put(key, value);
}
return map;
}
// Calling Method
public static Map<String, Object> convertJsonToMap(String json) {
Map<String, Object> map = new HashMap<String, Object>();
JSONObject jsonObject = null;
try {
if (null != json) {
jsonObject = new JSONObject(json);
map = getMap(jsonObject, json);
}
} catch (Exception e) {
throw new SystemException("Unable to read JSOn Object");
// TODO : Handle Exception
}
return map;
}