Convert part of nested Json object into Java Map - java

I have this Json:
{
"withDrawAccountNumber": "1.10.100.1",
"Amount": "1000",
"creditor": {
"2.20.200.2": "1700",
"2.20.200.1": "300"
}
}
i want to get the creditor's key value in HashMap, output must be like this:
"2.20.200.2": "1700",
"2.20.200.1": "300"
i dont have any idea how i must do this.

why not use this :
Map<String,String> testMap = new HashMap<String, String>();
String testJson = "{\r\n"
+ " \"withDrawAccountNumber\": \"1.10.100.1\",\r\n"
+ " \"Amount\": \"1000\",\r\n"
+ " \"creditor\": {\r\n"
+ " \"2.20.200.2\": \"1700\",\r\n"
+ " \"2.20.200.1\": \"300\"\r\n"
+ " }\r\n"
+ "}";
JSONObject ob = new JSONObject(testJson);
JSONObject cr = ob.getJSONObject("creditor");
Set<String> keys = cr.keySet();
for(String key : keys) {
testMap.put(key, cr.getString(key));
}
testMap.forEach((K,V)->System.out.println("key : "+K+" Value : "+V));

Gson gson = new Gson();
Map map = gson.fromJson(jsonData, Map.class);

I dont really see the purpose on why you would do that, but you could do something like this i guess:
JSONObject jsonObj = new JSONObject(obj);
HashMap<String,String> map = new HashMap<String,String>();
String value = jsonObj.getString("2.20.2001");
map.put("2.20.2001", value);
// ... use map here in what you want to achieve

Related

how to take json data in java map or array

I have the following data as json and I want to take it in java
"endPoints": {
"northAmerica": "https://ad-api.com",
"europe": "https://ad-api-eu.com",
"farEast": "https://ad-api-fe.com"
}
I have tried the below code but not working.
Map<String, Object> endPoints = objectMapper.readValue(JsonParser
.parseString(additionalInfo().get("endPoints").toString())
.getAsJsonObject(), new TypeReference<Map<String, Object>>() {
});
anyone can help me how to do it?
First you need to make your data is a valid json format,then you can use ObjectMapper to do it
public static void testJsonConvert() throws JsonProcessingException {
String data = "{\n" +
" \"endPoints\":{\n" +
" \"northAmerica\":\"https://ad-api.com\",\n" +
" \"europe\":\"https://ad-api-eu.com\",\n" +
" \"farEast\":\"https://ad-api-fe.com\"\n" +
" }\n" +
"}";
Map<String, Object> map = new ObjectMapper().readValue(data, HashMap.class);
System.out.println(map);
}
Test result:
Any JSON string can be mapped to HashMap data structure as Key and Value pair.
There is an answer already in the thread.
But If you want a map of endpoints, like North America & Europe, you need to go a level deeper.
ObjectMapper from Jackson Core library will help.
First, get a HashMap of the data, then again get the endpoint from the HashMap.
String data = "{\n" +
" \"endPoints\":{\n" +
" \"northAmerica\":\"https://ad-api.com\",\n" +
" \"europe\":\"https://ad-api-eu.com\",\n" +
" \"farEast\":\"https://ad-api-fe.com\"\n" +
" }\n" +
"}";
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(data, HashMap.class);
Map<String, Object> endPointMap = (Map<String, Object>) map.get("endPoints");
System.out.println(endPointMap);
result:
{northAmerica=https://ad-api.com, europe=https://ad-api-eu.com, farEast=https://ad-api-fe.com}

Get list of keys in Complex JSON Object (Java 8)

I am dealing with a JSON that looks like this :-
{
"key1": {
"key1.1": {
"nestedkey1": "something",
"nestedkey2": "something",
"nestedkey3": "Something"
},
"key1.2": {
"nestedkey1": "something",
"nestedkey2": "something",
"nestedkey3": "Something"
}
},
"key2": {
"key2.1": {
"nestedkey1": "something",
"nestedkey2": "something",
"nestedkey3": "Something"
},
"key2.2": {
"nestedkey1": "something",
"nestedkey2": "something",
"nestedkey3": "Something"
}
}...
And I don't know all the keys. I wish to obtain all the keys so that I can create a Map<String, Object> out of this. That map should look something like ("key1" -> Corresponding object)...
Is there a simple way to do this in Java?
String filePath ="src/main/resources/json/1.json";
FileReader reader = new FileReader(filePath);
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(reader);
Set<String> setKeys= jsonObject.keySet();
Map<String,Object> yourMap= new HashMap<>();
for (String key:setKeys) {
yourMap.put(key,jsonObject.get(key));
}
yourMap is ready!
Using Jackson JSON library, this json may be parsed as a Map<String, Object> using TypeReference:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class JsonTest {
public static void main(String[] args) throws JsonProcessingException {
String json = "{\n"
+ "\"key1\": {\n"
+ " \"key1.1\": {\n"
+ " \"nestedkey1\": \"something\",\n"
+ " \"nestedkey2\": \"something\",\n"
+ " \"nestedkey3\": \"Something\"\n"
+ " },\n"
+ " \"key1.2\": {\n"
+ " \"nestedkey1\": \"something\",\n"
+ " \"nestedkey2\": \"something\",\n"
+ " \"nestedkey3\": \"Something\"\n"
+ " }\n"
+ "},\n"
+ "\"key2\": {\n"
+ " \"key2.1\": {\n"
+ " \"nestedkey1\": \"something\",\n"
+ " \"nestedkey2\": \"something\",\n"
+ " \"nestedkey3\": \"Something\"\n"
+ " },\n"
+ " \"key2.2\": {\n"
+ " \"nestedkey1\": \"something\",\n"
+ " \"nestedkey2\": \"something\",\n"
+ " \"nestedkey3\": \"Something\"\n"
+ " }\n"
+ "}}"; // make sure the json is valid and closing } is available
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(json, new TypeReference<>() {});
System.out.println(map);
}
}
To get the list of all keys, a recursive method needs to be implemented to iterate over the entries of the top-level map and add keys:
public static List<String> getKeys(Map<String, Object> map) {
List<String> keys = new ArrayList<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
keys.add(entry.getKey());
if (entry.getValue() instanceof Map) {
Map<String, Object> nested = (Map<String, Object>) entry.getValue();
keys.addAll(getKeys(nested));
}
}
return keys;
}
Similarly, a list of "prefixed" keys may be created:
public static List<String> getPrefixedKeys(String prefix, Map<String, Object> map) {
List<String> keys = new ArrayList<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = prefix + entry.getKey();
keys.add(key);
if (entry.getValue() instanceof Map) {
Map<String, Object> nested = (Map<String, Object>) entry.getValue();
keys.addAll(getPrefixedKeys(key + "/", nested));
}
}
return keys;
}
// test
System.out.println(getPrefixedKeys("/", map));
Output:
[/key1, /key1/key1.1, /key1/key1.1/nestedkey1, /key1/key1.1/nestedkey2, /key1/key1.1/nestedkey3,
/key1/key1.2, /key1/key1.2/nestedkey1, /key1/key1.2/nestedkey2, /key1/key1.2/nestedkey3,
/key2, /key2/key2.1, /key2/key2.1/nestedkey1, /key2/key2.1/nestedkey2, /key2/key2.1/nestedkey3,
/key2/key2.2, /key2/key2.2/nestedkey1, /key2/key2.2/nestedkey2, /key2/key2.2/nestedkey3]
The computing task is to output field names of all levels in JSON records of indefinite number of levels. The code will be lengthy if you try to handle such a scenario in Java.
It is convenient to do this in SPL, the open-source Java package. Three lines of code are enough:
A
B
1
=i=0,json(file("records.json").read())
2
func recurse(r)
>i+=1,r.fno().run(tmp=eval("r.#"/~),B1=B1.to(:i-1)|r.fname(~),output(B1.concat("->")),if(ifr(tmp),func(recurse,tmp),(B1=B1|tmp)))
3
=func(recurse,A1)
SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as jsonkeys.splx and invoke it in Java as you call a stored procedure:
…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call jsonkeys()");
st.execute();
…

Is there any way to put both string and array in single HashMap?

i'm moving from php to Java. and i'm trying to achieve something like below in Java :
$user = array(
"firstname" => "myname",
"lastname" => "surname",
"phone" => array(
"home" => "123213213213",
"office" => "312321321312312",
"mobile" => "4532134213131312"
)
)
is there any way to do like that in java?
Thanks!
There are are few ways to make it closer, but nothing as convenient as that.
Example 1:
Map<String, Object> user = new HashMap<String, Object>() {
{
put("firstname", "myname");
put("lastname", "surname");
put("phone", new HashMap<String, String>() {
{
put("home", "123213213213");
put("office", "312321321312312");
put("mobile", "4532134213131312");
}
});
}
};
Update example:
((Map)user.get("phone")).put("mobile2", "123");
Adding another map:
user.put("address", new HashMap<String, Object>());
(could perhaps be improved by use of putIfAbsent method, or the merge-methods)
Printing current contents:
System.out.println(user);
Gives:
{firstname=myname, address={}, phone={mobile2=123, mobile=4532134213131312, office=312321321312312, home=123213213213}, lastname=surname}
For instance you can use the following code :
Map<String, Object> map = new HashMap<>();
map.put("firstname", "myname");
Map<String, String> phones = new HashMap<>();
phones.put("home" , "123213213213");
phones.put("office" , "312321321312312");
phones.put("mobile" , "4532134213131312");
map.put("phones", phones);
You could use the JSON API in Java to create an object in the format you like. Here is the documentation of the JSON API
http://www.oracle.com/technetwork/articles/java/json-1973242.html
Example:
String stringToParse = "{" +
"firstname: \"myname\"," +
"lastname: \"surname\"," +
"phone: [ " +
" { home: \"123213213213\" }, " +
" { office: \"312321321312312\" }," +
" { mobile: \"4532134213131312\" }" +
"]" +
"}";
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(stringToParse);
It is "possible" but I don't think it would be good convention (unless there is another way I am unaware of). I believe that this would work:
HashMap<String, Object> hm = new HashMap<String, Object>();
I would think that you would have to use a List object type instead of a array data type for a HashMap. If I were doing this, I would likely create my own class that handles this situation.

How to merge two json Strings into one in java

If we have given 2 Strings of type json, how can we merge them into single json String in java?
e.g.
String json1 = {
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S"
}
}
}
String json2 = {
"glossary": {
"title": "person name",
"age": "25"
}
}
Should produce
String mergedJson = {
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S"
},
"age": "25"
}
}
Below code should do it, with a couple of assumptions:
You are using ObjectMapper of Jackson library (com.fasterxml.jackson.databind.ObjectMapper) to serialise/deserialise json
fields of json1 will always overwrite json2 while merging
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map1 = mapper.readValue("json1", Map.class);
Map<String, Object> map2 = mapper.readValue("json2", Map.class);
Map<String, Object> merged = new HashMap<String, Object>(map2);
merged.putAll(map1);
System.out.println(mapper.writeValueAsString(merged));
Here is the code which recursively merges two jsons. This outputs as excepted:
NOTE: This is deep merge, not shallow merge ( similar concept used for shall vs deep copy)
private static JsonObject merge(JsonObject json1Obj, JsonObject json2Obj) {
Set<Entry<String, JsonElement>> entrySet1 = json1Obj.entrySet();
for (Entry<String, JsonElement> entry : entrySet1) {
String key1 = entry.getKey();
if (json2Obj.get(key1) != null) {
JsonElement tempEle2 = json2Obj.get(key1);
JsonElement tempEle1 = entry.getValue();
if (tempEle2.isJsonObject() && tempEle1.isJsonObject()) {
JsonObject mergedObj = merge(tempEle1.getAsJsonObject(),
tempEle2.getAsJsonObject());
entry.setValue(mergedObj);
}
}
}
Set<Entry<String, JsonElement>> entrySet2 = json2Obj.entrySet();
for (Entry<String, JsonElement> entry : entrySet2) {
String key2 = entry.getKey();
if (json1Obj.get(key2) == null) {
json1Obj.add(key2, entry.getValue());
}
}
return json1Obj;
}
Consider using a library that does this job for you, like JSON Merge, available at Maven Central.
You will get the desired result with a single line of code (you may ignore the String declarations if you already have the JSONObjects previously loaded):
String json1 = "{\n"
+ " \"glossary\": {\n"
+ " \"title\": \"example glossary\",\n"
+ " \"GlossDiv\": {\n"
+ " \"title\": \"S\"\n"
+ " }\n"
+ " }\n"
+ " }";
String json2 = "{\n"
+ " \"glossary\": {\n"
+ " \"title\": \"person name\",\n"
+ " \"age\": \"25\"\n"
+ " }\n"
+ " }";
JSONObject result = new JsonMerger<>(JSONObject.class).merge(json2, json1);
Note: the first JSON parameter passed to the merge method will always have more precedence/importance than the second one in case of key collisions.
This library works with Jackson, Gson, and other JSON providers as well.
So I'm quite late to the party but I wanted to share my solution if anybody stumbles across this.
You can deeply merge two json strings with com.fasterxml.jackson.core:jackson-databind ObjectMapper.readerForUpdating().
In this scenario you pass in two Json as String and merge them via readerForUpdating (untested code):
public String mergeJsonStrings(String json1, String json2) {
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.readerForUpdating(json1);
String result = reader.readValue(json2);
return result;
}
I used similar code to merge a property into an existing dataset. In this example the SomeProperties class contains a hashmap which holds the properties for a specific user. The passed in propertiesString is a single dot separated property e.g. some.random.property=value. The property will be transformed into a JsonNode with com.fasterxml.jackson.dataformat:jackson-dataformat-properties.
public SomeProperties mergeProperties(SomeProperties someProperties, String propertiesString) {
JavaPropsMapper javaPropsMapper = new JavaPropsMapper();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = javaPropsMapper.readTree(propertiesString);
ObjectReader objectReader = mapper.readerForUpdating(someProperties.getProperties());
HashMap<String, Object> mergedProperties = objectReader.readValue(jsonNode);
someProperties.setProperties(mergedProperties);
return someProperties;
}
In both cases everything passed into objectReader.readValue() will override existing keys.

How to get all the keys of json in java using Gson or org.json library? [duplicate]

This question already has answers here:
How can I access each key and value in JSONArray
(2 answers)
Closed 7 years ago.
For example from the following json, id, items, fromNumber should be retrieved.
The json can be having n number of nesting.
{
"items": [{
"id": 633706061003,
"fromNumber": "16572307534",
"contact": {
"id": 499354453003,
"homePhone": "16572307534"
},
"records": [{
"id": 353389055003,
"result": "LA",
"recordings": [{
"id": 16427622003,
}]
}]
}],
"limit": 100,
"offset": 0,
"totalCount": 5949
}
I have implemented the below code, but in this code I have to tell the level of nesting
String prefix = "";
/*
* Root Array
*/
JsonArray rootArray = new JsonParser().parse(json).getAsJsonArray();
for (int i = 0; i < rootArray.size(); i++) {
/*
* Single object in root array while iterations. for id, properties, tags etc.
*/
JsonObject rootArrayObject = rootArray.get(i).getAsJsonObject();
Set<Map.Entry<String, JsonElement>> rootArrayObjectEntrySet = rootArrayObject.entrySet();
/*
* Getting the keys and values of RootArray Single Object
*/
for (Map.Entry<String, JsonElement> entryChild : rootArrayObjectEntrySet) {
prefix = entryChild.getKey();
/*
* Getting each object, key or array as an element
*/
JsonElement rootArrayObjElement = rootArrayObject.get(entryChild.getKey());
if(rootArrayObjElement.isJsonArray()){
/*
* Getting array's object in single object of root array. Example: tags
*/
JsonArray rootArrayObjArray = rootArrayObjElement.getAsJsonArray();
for (int j = 0; j < rootArrayObjArray.size(); j++) {
}
}else if(rootArrayObjElement.isJsonObject()){
/*
* Single object in root array
*/
JsonObject rootArrayObjObj = rootArrayObjElement.getAsJsonObject();
Set<Map.Entry<String, JsonElement>> rootArrayObjObjEntrySet = rootArrayObjObj.entrySet();
for (Map.Entry<String, JsonElement> rootArrayObjObjChild : rootArrayObjObjEntrySet) {
/*
* Getting each object, key or array as an element
*/
JsonElement rootArrayObjObjElement = rootArrayObjObj.get(rootArrayObjObjChild.getKey());
if(rootArrayObjObjElement.isJsonPrimitive()){
}else if(rootArrayObjObjElement.isJsonArray()){
JsonArray rootArrayObjArray = rootArrayObjObjElement.getAsJsonArray();
for (int j = 0; j < rootArrayObjArray.size(); j++) {
}
}
}
}else if(rootArrayObjElement.isJsonPrimitive()){
}
}
}
You can try something like below :
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class GSonWay {
public static void main(String[] args) throws Exception {
String jsonString = "{\n"
+ "\"items\": [{\n"
+ " \"id\": 633706061003,\n"
+ " \"fromNumber\": \"16572307534\",\n"
+ "\n"
+ " \"contact\": {\n"
+ " \"id\": 499354453003,\n"
+ " \"homePhone\": \"16572307534\"\n"
+ " },\n"
+ "\n"
+ " \"records\": [{\n"
+ " \"id\": 353389055003,\n"
+ " \"result\": \"LA\",\n"
+ " \"recordings\": [{\n"
+ " \"id\": 16427622003\n"
+ " }]\n"
+ " }]\n"
+ "}],\n"
+ "\"limit\": 100,\n"
+ "\"offset\": 0,\n"
+ "\"totalCount\": 5949\n"
+ "\n"
+ "}";
List keys1 = getKeysFromJson(jsonString);
System.out.println(keys1.size());
System.out.println(keys1);
}
static List getKeysFromJson(String jsoString) throws Exception {
Object things = new Gson().fromJson(jsoString, Object.class);
List keys = new ArrayList();
collectAllTheKeys(keys, things);
return keys;
}
static void collectAllTheKeys(List keys, Object o) {
Collection values = null;
if (o instanceof Map) {
Map map = (Map) o;
keys.addAll(map.keySet()); // collect keys at current level in hierarchy
values = map.values();
} else if (o instanceof Collection) {
values = (Collection) o;
} else{return;}
for (Object value : values) {
collectAllTheKeys(keys, value);
}
}
}
Output :
[items, limit, offset, totalCount, id, fromNumber, contact, records, id, homePhone, id, result, recordings, id]
Gson is one of the best ways to decode JSON file. Gson requires POJO classes, which can be manually generated but is tiresome. The best way to develop POJO classes is to visit jsonschema2pojo.org. They will generate the required POJO classes for you.
Let's say the class is JsonData.java
So in your code, you have to create a Gson object as well as an object of JsonData class.
String jsonFile = "____let this be your json data___"
Gson gson = new Gson();
JsonData jsonData = new JsonData();
jsonData = gson.fromJson(jsonFile, JsonData.class);
now jsonData will have all the data's retrieved from the json file. If you want to get fromNumber you can just call getFromNumber() which will be a method inside JsonData class. Similarly you can call other values too.
Try using third party services like jsonschema2pojo.org for improving your productivity.

Categories

Resources