Jackson map deserialization - value replacement - java

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

Related

How can i deseralize a dynamic generated JSON Object?

Im having trouble to deserialize the object back into the original class. The problem is that the Component class have to be serialized in that spezific way with the features beeing a seperate list/set object.The attributes have to be seperate key/value pairs. If i try to deserialize the JSON/object back, i get an "can´t construct instance of LinkedHashMap" error.
Here is the class to parse to JSON
public class Component {
private Set<Attribute> attributes;
private Set<Feature> features;
}
public class Attribute {
private String type;
private String key;
private String value;
}
public class Feature {
private String key;
private String value;
}
Here is the serializer
public class ComponentSerializer extends StdSerializer<Component> {
public ComponentSerializer(){
this(null);
}
public ComponentSerializer(Class<Component> c){
super(c);
}
#Override
public void serialize(Component com, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
for(Attribute att : com.getAttributes()){
gen.writeStringField(att.getKey(),att.getValue());
}
Set<Feature> features = new HashSet<Feature>();
for(Feature ftr : com.getFeatures()){
features.add(new Feature(ftr.getKey(), ftr.getValue()));
}
gen.writeObjectField("features", features);
gen.writeEndObject();
}
}
The outcome JSON is something like
{
"Foo": "Fooo",
"Bar": "Barr",
...
"features": [
{
"key": "foo",
"value": "bar"
},
{
"key": "bar",
"value": "foor"
}
...
]
}
My attempt on deserialization
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(p.getCodec().readTree(p).toString(), new TypeReference<Map<String, Object>>() {
});
Set<Attribute> attributes = new HashSet<>();
Set<Feature> features = new HashSet<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("features")){
//Here i cant create the Set<Features> from the object without the exception
continue;
}
attributes.add(new Attribute("", entry.getKey(), entry.getValue().toString()));
}
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(p.getCodec().readTree(p).toString(), new TypeReference<Map<String, Object>>() {});
Set<Attribute> attributes = new HashSet<>();
Set<Feature> features = new HashSet<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("features")) {
List<LinkedHashMap> featureList = (List<LinkedHashMap>) entry.getValue();
featureList.stream().forEach(feature -> {
features.add(new Feature(feature.get("key").toString(), feature.get("value").toString()));
});
continue;
}
attributes.add(new Attribute("", entry.getKey(), entry.getValue().toString()));
}

Json String to map convertor,

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;
}
}

Jackson: how to convert flat json into nested json

How can I convert a json string like
{
"a.b": 1,
"a.c.d": 2
}
into json string
{
"a": {
"b": 1,
"c": {
"d": 2
}
}
}
by using ObjectMapper?
The easiest option is to create custom deserializer or custom been with #JsonAnySetter and #JsonAnyGetter Here is example:
public static final String json = "{\"a.b\": 1,\"a.c.d\": 2}";
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
HelperBean bean = mapper.readValue(json, HelperBean.class);
System.out.println(mapper.writeValueAsString(bean));
// result: {"a":{"b":1,"c":{"d":2}}}
}
public static class HelperBean{
#JsonIgnore
private Map<String, Object> data = new TreeMap<>();
#JsonAnySetter
public void setDays(String key, Object value){
String[] parts = key.split("\\.");
Map<String, Object> currMap = data;
for (int i = 0; i< parts.length; i++){
String part = parts[i];
Object subMap = currMap.get(part);
if (i == parts.length - 1) // last node
currMap.put(part, value);
else if(subMap == null){ // new node
subMap = new TreeMap<>();
currMap.put(part, subMap);
currMap = (Map<String, Object>) subMap;
}else if (subMap instanceof Map){ // existing node
currMap.put(part, subMap);
currMap = (Map<String, Object>) subMap;
} else { // node conflict
// handle exception when a.b = 1 and a.b.c = 1
}
}
}
#JsonAnyGetter
public Map<String, Object> getData() {
return data;
}
}

Rename map keys in GSON according to FieldNamingPolicy

Say I'm building my GSON object like this
new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
and now I want to deserialize the following JSON
{
"MyMap" : {
"Key1" : "Foo",
"Key2" : "Bar"
}
}
into the following class (which is working just fine)
public class MapClass {
Map<String,String> myMap;
}
but I also would like the keys to be named "key1" and "key2". How would I go about this?
You can try in this way:
try {
JSONObject jObj = new JSONObject("{"
+ " \"MyMap\" : {"
+ " \"Key1\" : \"Foo\","
+ " \"Key2\" : \"Bar\""
+ " }"
+ "}"); // this parses the json
JSONObject jObjt = jObj.getJSONObject("MyMap");
//old version with out GSON
Map<String, String> map = new HashMap();
Iterator itr = jObjt.keys();
while (itr.hasNext()) {
String key = (String) itr.next();
String value = jObjt.getString(key);
map.put(key, value);
}
//desalinized one with GSON
Map<String, String> map1 = new Gson().fromJson(jObjt.toString(), HashMap.class);
for (String str : map1.keySet()) {
System.out.println("k:" + str + " v:" + map1.get(str));
}
} catch (JSONException ex) {
//log the error
}
FieldNamingPolicy is applied to fields of json value. It is not possible to apply this to maps' keys (a map which has key, value pairs) at json.
Easy solution:
After deserialization, iterate over your map and rename key names. i.e. Key1 to key1 and Key2 to key2.
Other solution:
Write a custom TypeAdapter which handles deserialization process and renames keys.
public class MapClassTypeAdapter extends TypeAdapter<MapClass> {
#Override
public MapClass read(JsonReader in) throws IOException {
final MapClass mapClassInstance = new MapClass();
mapClassInstance.myMap = new HashMap<String, String>();
in.beginObject();
if("myMap".equalsIgnoreCase(in.nextName())) {
in.beginObject();
while (in.hasNext()) {
String key = in.nextName();
// You want keys as camel case
String newKey = key.substring(0,1).toLowerCase() + key.substring(1);
String value = in.nextString();
mapClassInstance.myMap.put(newKey, value);
}
in.endObject();
}
in.endObject();
return mapClassInstance;
}
#Override
public void write(JsonWriter out, MapClass mapClass) throws IOException {
throw new RuntimeException("MapClassTypeAdapter.write method not implemented yet!");
}
}
Test Other solution:
String json = "{\"myMap\":{\"Key1\":\"Foo\",\"Key2\":\"Bar\"}}";
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MapClass.class, new MapClassTypeAdapter());
final Gson gson = gsonBuilder.create();
MapClass mapClass = gson.fromJson(json, MapClass.class);

Convert a JSON String to a HashMap

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);
}

Categories