Java MAP to JSON - java

First of all, I'm new to Java so please be kind with me :-).
I have a map and I want to parse into JSON Object:
private static final Map<String, Queue<String>> myMap = new HashMap<String, Queue<String>>();
My Key is the login (email) of a user.
I would like to create a JSON Object like this one :
{
Login1: {
itemOne: 'item one',
itemTwo: 'item two'
},
Login2: {
itemOne: 'item one',
itemTwo: 'item two'
}
}
I have tried it using JSONObject or ObjectMapper but it didn't worked. I'm looking for some tips / advices.
Thanks,

The way you have it now, parsing Map<String, Queue<String>> into valid JSON would mean that you'd get something like this:
{
queueOne: {
itemOne: 'item one',
itemTwo: 'item two'
},
queueTwo: {
itemOne: 'item one',
itemTwo: 'item two'
}
}
If there's only one queue, putting it in a map isn't necessary. If there's multiple you'll have to iterate over the Map, create a JSONArray from the Queue and then put a JSONObject with the String as key and Queue as value into a main JSONArray.

It's strange, but the key of your map is never used in your example.
Completed example would be:
{
"key":{
"item2":"SecondItemOnTheQueue",
"item1":"FirstItemOnTheQueue",
"item3":"ThirdItemOnTheQueue"
}
}
Java code below:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import org.json.JSONObject;
public class App {
public static void main(String[] args) {
Map<String, Queue<String>> map = new HashMap<String, Queue<String>>();
map.put("key", new LinkedList<String>(){{
add("FirstItemOnTheQueue");
add("SecondItemOnTheQueue");
add("ThirdItemOnTheQueue");
}});
System.out.println(generateFromMapOfQueues(map));
}
private static JSONObject generateFromMapOfQueues(Map<String, Queue<String>> map) {
JSONObject result = new JSONObject();
for(String key : map.keySet()){
JSONObject queueJson = new JSONObject();
int initSize = map.get(key).size();
for (int i = 0; i < initSize; i++) {
queueJson.append("item" + (i + 1), map.get(key).poll());
}
result.put(key, queueJson);
}
return result;
}
}
The map after completion will contain empty queues... That's the only problem.

Related

Concatenate all JSON key-value pairs into a String

I have input:
{
"Id": 200,
"TimeStamp": 1596466800,
"Animal": "cat"
}
I need to concatenate all key-value pairs in one String
I need output:
"Id200Timestamp1596466800Animalcat"
Usually you use a third-party library for parsing JSON. There are several. The below code uses Gson.
Note that the below code is not terribly robust, it assumes that there are no nested elements and that the values are all primitives. That is what you specifically asked for, i.e. specific input and specific output, and I am posting a solution that achieves what you specifically asked for.
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import java.util.Map;
import java.util.Set;
public class GsonTst0 {
public static void main(String[] args) {
String json = "{ \"Id\": 200, \"TimeStamp\": 1596466800, \"Animal\": \"cat\"}";
JsonElement root = JsonParser.parseString(json);
if (root.isJsonObject()) {
JsonObject jsonObj = root.getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entries = jsonObj.entrySet();
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, JsonElement> entry : entries) {
sb.append(entry.getKey());
JsonElement elem = entry.getValue();
JsonPrimitive prim = elem.getAsJsonPrimitive();
if (prim.isNumber()) {
sb.append(prim.getAsBigDecimal());
}
else {
sb.append(prim.getAsString());
}
}
System.out.println(sb);
}
}
}
Running the above code prints the following:
Id200TimeStamp1596466800Animalcat

Using JAVA, how to iterate (or traverse?) through json file with more than one level of data?

I have a snippet of a snippet of a json file that has 3 levels of key,value data I need to access. The tricky part is, sometimes it's a list and sometimes a tuple (or I can be corrected). Some have referred to this file as a map of maps, but I'm guessing that's just nested hashmaps.
Problem Statement: I can iterate through the first level of this JSON, but cannot iterate through the lists inside "data". Java barks at me saying I can't do that with a string. Sometimes the values under data/(next level random word) starts with a bracket [ then a squiggly and sometimes just a squiggly {.
There will be a few lines in there that won't make sense because I was trying different methods to unwrap those sublists.
Key is: raindrop, Value is : {".type":"uri",".value":"http:blahblahblah.info"}
Key is: apex, Value is : [{".type":"inet4",".value":"3.3.3.3"},{".type":"inet4",".value":"3.3.3.3"},{".type":"inet4",".value":"3.3.3.3"},{".type":"inet4",".value":"3.3.3.3"},{".type":"inet4",".value":"3.3.3.3"}]
This is the example of the json file I'm trying to cycle through to get these values so I can determine what kind of value it has (switch statement to count distinctive types).
{
"data": {
"coffee": [
{
".type": "bigdec",
".value": "2626262626.234234234234234"
And here is what I have so far that just gives me the first layer of data.
package com.mycompany.app;
import java.util.regex.Pattern;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.util.*;
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.io.FileReader;
public class App {
private static Object object;
public void countDistinctValues(String[] args){}
#SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception
{
String filePath = "D:/sandbox/map03/my-app/data.json";
// parsing file
Object obj = new JSONParser().parse(new FileReader(filePath));
// typecasting obj to JSONObject
JSONObject jo = (JSONObject) obj;
System.out.println("--------------------------------------------------------------------");
Map theData = ((Map)jo.get("data"));
Map<String, String> runningMap = new HashMap<>();
Map<String, String> tempMap = new HashMap<>();
int matchCount = 0;
// iterating address Map
Iterator<Map.Entry> itr1 = theData.entrySet().iterator();
while (itr1.hasNext()) {
Map.Entry pair = itr1.next();
// System.out.println(pair.getKey() + " : " + pair.getValue());
runningMap.put(pair.getKey().toString(),pair.getValue().toString());
}
// THIS ENTIRE SECTION BELOW IS TO JUST TRYING TO COUNT EACH LEVEL - THOUGHT I COULD TAKE THE VALUE INTO A VARIABLE AND THEN ITERATE THROUGH IT, BUT IT ONLY SEES IT AS A STRING
System.out.println("--------------------------------------------------------------------");
for (Map.Entry<String, String> newPair : runningMap.entrySet()) {
System.out.println(String.format("Key is: %s, Value is : %s", newPair.getKey(), newPair.getValue()));
String pattern = ".*type.*";
boolean matches = Pattern.matches(pattern, newPair.getValue());
if (matches == true) {matchCount++; }}
System.out.println("--------------------------------------------------------------------");
System.out.println("matches = " + matchCount);
System.out.println("--------------------------------------------------------------------");
// System.out.println("Test Data --> " + newPair);
}
/* for (Map.Entry<String, String> book: pair.entrySet()) {
System.out.println("key: " + book.getKey() + " value: " + book.getValue());
} */
}
```

How to convert a string to JSONArray

I am hitting an api and getting a string response. The response is something like this
"["VU","Vanuatu",["Pacific/Efate","(GMT+11:00) Efate"],"VN","Vietnam",["Asia/Saigon","(GMT+07:00) Hanoi"]]"
And i want to convert this string into a json array of below type
[{"id":"VN","name":"Vanuatu","timezones":[{"id":Pacific/Efate,"name":"(GMT+11:00) Efate}]},"id":"VN","name":"Vietnam",[{"id":"Asia/Saigon","name":"(GMT+07:00) Hanoi"}]]
Can someone help
Looking at your String response, I've created a regular expression that will create four groups out of your response.
DEMO
Assuming that your output would come always in groups of four (i.e., id, name and timezones_id, timezones_name), this regular expression, would extract 4 groups out of the input string that you've provided:
Regex:
"([^"]*)",\s*"([^"]*)",\s*\["([^"]*)",\s*"([^"]*)"\]
Matches
Match 1
Full match 1-56 `"VU", "Vanuatu", ["Pacific/Efate", "(GMT+11:00) Efate"]`
Group 1. 2-4 `VU`
Group 2. 8-15 `Vanuatu`
Group 3. 20-33 `Pacific/Efate`
Group 4. 37-54 `(GMT+11:00) Efate`
Match 2
Full match 58-111 `"VN", "Vietnam", ["Asia/Saigon", "(GMT+07:00) Hanoi"]`
Group 1. 59-61 `VN`
Group 2. 65-72 `Vietnam`
Group 3. 77-88 `Asia/Saigon`
Group 4. 92-109 `(GMT+07:00) Hanoi`
 
Now once you've extracted these 4 groups, You can simply add appropriately in ArrayList and List and create JSONArray out of those lists.
The following program is self-explanatory with the inputs and outputs.
Input
["VU","Vanuatu",["Pacific/Efate","(GMT+11:00) Efate"],"VN","Vietnam",["Asia/Saigon","(GMT+07:00) Hanoi"]]
Output
[{"timezones":{"name":"(GMT+11:00) Efate","id":"Pacific/Efate"},"name":"Vanuatu","id":"VU"},{"timezones":{"name":"(GMT+07:00) Hanoi","id":"Asia/Saigon"},"name":"Vietnam","id":"VN"}]
Formatted Output
[{
"id" : "VU",
"name" : "Vanuatu",
"timezones" : {
"name" : "(GMT+11:00) Efate",
"id" : "Pacific/Efate"
}
}, {
"id" : "VN",
"name" : "Vietnam",
"timezones" : {
"name" : "(GMT+07:00) Hanoi",
"id" : "Asia/Saigon"
}
}
]
Code
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONException;
public class Test
{
public static void main(String[] args) throws IOException, JSONException {
String serverResponse = "[\"VU\", \"Vanuatu\", [\"Pacific/Efate\", \"(GMT+11:00) Efate\"], \"VN\", \"Vietnam\", [\"Asia/Saigon\", \"(GMT+07:00) Hanoi\"]]";
Map<String, Object> prop, innerProp;
List<Object> arr = new ArrayList<>(), obj;
String pattern = "\"([^\"]*)\",\\s*\"([^\"]*)\",\\s*\\[\"([^\"]*)\",\\s*\"([^\"]*)\"\\]";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(serverResponse);
while (m.find()) {
prop = new HashMap<>();
prop.put("id", m.group(1));
prop.put("name", m.group(2));
innerProp = new HashMap<>();
innerProp.put("id", m.group(3));
innerProp.put("name", m.group(4));
prop.put("timezones", innerProp);
arr.add(prop);
}
JSONArray jsonArray = new JSONArray(arr);
System.out.println(jsonArray.toString());
}
}
An option you have is to first create a JSONArray off of the string, and then read elements 3 by 3 from that array to create your output:
public static void main(String[] args) {
String input = "[\"VU\",\"Vanuatu\",[\"Pacific/Efate\",\"(GMT+11:00) Efate\"],\"VN\",\"Vietnam\",[\"Asia/Saigon\",\"(GMT+07:00) Hanoi\"]]";
JSONArray inputArray = new JSONArray(input);
JSONArray outputArray = new JSONArray();
for (int i = 0; i < inputArray.length(); i += 3) {
JSONObject obj = readCountry(inputArray, i);
outputArray.put(obj);
}
System.out.println(outputArray);
}
private static JSONObject readCountry(JSONArray array, int index) {
JSONObject country = new JSONObject();
country.put("id", array.getString(index));
country.put("name", array.getString(index + 1));
country.put("timezones", readTimeZones(array.getJSONArray(index + 2)));
return country;
}
private static JSONArray readTimeZones(JSONArray array) {
JSONArray timezones = new JSONArray();
JSONObject timezone = new JSONObject();
timezone.put("id", array.getString(0));
timezone.put("name", array.getString(1));
timezones.put(timezone);
return timezones;
}
You may add some error handling to fail gracefully or even recover with best effort if the input doesn't match.

read a string in JSON format in JAVA

I want to read a string as a JSON format(it doesn't have to be JSON, but it seems like JSON format) and represent it to a hashMap(key : Keyword, value : COUNT)
for example, assume I have a String.
String s ={"Welcome":1,"Hi":2,"Hello":1,"Jin":1};
Then, make it classification.(for Hashmap key --> word, value--> number). final result would be something like as below.
HashMap<String,String> result;
result.get("Jin"); // output : 1
result.get("Hi"); // output : 2
but my codes, it doesn't go with right way.
JSONParser parser = new JSONParser();
Object obj = parser.parse(s);
JSONArray array = new JSONArray();
array.add(obj);
System.out.println(array.get(0)); //output: {"Welcome":1,"Hi":2,"Hello":1,"Jin":1}
can it be possible with JSON? or should I split them one by one? (such as split them with "," first and ":" ... so on)
Please give me your kind advice.
Try with below code snippet.
public static void main(final String[] args) throws ParseException {
String s = "{\"Welcome\":1,\"Hi\":2,\"Hello\":1,\"Jin\":1}";
JSONParser parser = new JSONParser();
HashMap<String, Long> obj = (HashMap<String, Long>) parser.parse(s);
for(String key : obj.keySet()) {
System.out.println("Key:" + key + " value:" + obj.get(key));
}
}
You can use org.json to fulfill your requirement.
E.g.
String s = "{\"Welcome\":1,\"Hi\":2,\"Hello\":1,\"Jin\":1}";
JSONObject result = new JSONObject(s);
System.out.println(result.get("Jin")); // output : 1
System.out.println(result.get("Hi")); // output : 2
The easiest to achieve this is by using JACKSON parsers.
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
String s = "{\"Welcome\":1,\"Hi\":2,\"Hello\":1,\"Jin\":1}";
ObjectMapper mapper = new ObjectMapper();
Map<String, String> map = mapper.readValue(s, new TypeReference<HashMap<String, String>>() {
});
map.forEach((k, v) -> System.out.println("Key is " + k + " value is " + v));
Prints :
Key is Hi value is 2
Key is Hello value is 1
Key is Welcome value is 1
Key is Jin value is 1
Its a json object not an array...
try this one :
JSONObject jsonObj = new JSONObject(jsonString.toString());
Use Google JSON i.e gson library(2.6.2) and your problem will be solved.
Please have a look to the following code
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class StackOverFlowQuestionset {
public static void main(String[] args) {
String s ="{\"Welcome\":1,\"Hi\":2,\"Hello\":1,\"Jin\":1}";
HashMap<String,String> result=new HashMap<String,String>();
Gson gson = new Gson();
JsonElement jsonElement = gson.fromJson(s, JsonElement.class);
JsonObject jsonObject = jsonElement.getAsJsonObject();
Set<Entry<String, JsonElement>> jsonEntrySet = jsonObject.entrySet();
for(Entry<String, JsonElement> entry:jsonEntrySet){
result.put(entry.getKey(), entry.getValue().toString());
}
System.out.println(result.get("Jin"));
System.out.println(result.get("Welcome"));
System.out.println(result.get("Hi"));
}
}

How to Parse JSON with dynamic Keyname?

I have a JSON response like this.
{
"array": [
{
"object1": {
"aa": "somevalue1",
"bb": "somevalue2",
"cc": "somevalue3"
}
},
{
"object2": {
"aa": "somevalue4",
"bb": "somevalue5",
"cc": "somevalue6"
}
}
]}
Now I can get a JSON array from above response. I want read the value aa,bb,cc from object object1 and object2 in a for loop.
JSON is dynamic, I mean that object2 can also appear before object1 (in reverse order) and there is chances that I might get one more object(object3) with same structure OR only one (object1 or object2 or object3).
I dont want to do like this as I failed in :
JSONArray jsonArray = json.getJSONArray("array");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i).getJSONObject("object1");
}
So my question is HOW can I read those values aa,bb,cc without depending on object name or number of object (object1 or object2 or object3)?
It looks like each item in the array only has 1 key/value pair which holds another json object which then has several.
If this is the case, then you could probably do something like this:
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONObject innerObject = jsonObject.getJSONObject(jsonObject.keys().next().toString());
/// do something with innerObject which holds aa, bb, cc
}
You simply grab the 1st key in the wrapping object, and use that to grab the inner json object.
I think you should have next Java-side structure of classes:
Entity - class that will hold aa, bb and cc fields
Container - a class that will consist of two fields - Name and Entity, where Name can store object1, object2 or whatever.
Then, you should deserialize provided JSON into collection/array of Container entities.
Hope this helps.
Update: please check this example Collection deserialization
You should work with dynamic structures like java.util.Map. Try with this:
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public class JsonTest {
public static void main(String[] args) {
String json = "{\"array\": [{\"object1\": {\"aa\": \"somevalue1\",\"bb\": \"somevalue2\",\"cc\": \"somevalue3\"}},{\"object2\": {\"aa\": \"somevalue4\",\"bb\": \"somevalue5\",\"cc\": \"somevalue6\"}}]}";
System.out.println(json);
final MyJson parseJsonSpecification = parseJsonSpecification(json);
System.out.println(parseJsonSpecification.array.get(0).get("object1"));
System.out.println(parseJsonSpecification);
}
public static MyJson parseJsonSpecification(String jsonString) {
try {
if (StringUtils.isBlank(jsonString)) {
return new MyJson();
}
MyJson ret;
ret = new ObjectMapper().readValue(jsonString, new TypeReference<MyJson>() {
});
return ret;
} catch (Exception ex) {
throw new IllegalArgumentException("La expresión '" + jsonString + "' no es un JSON válido", ex);
}
}
}
class MyJson {
public List<Map<String, Object>> array;
}

Categories

Resources