How to convert a string to JSONArray - java

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.

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());
} */
}
```

Get JSONArray without Arrayname in method

I need to get JSONArray from my data in string but without mentioning the arrayname as follows. It should get Array name itself from JSON data.
Here is my code
String metadata = result.getMetaData();
JSONObject jsonObject = new JSONObject(metadata);
JSONArray jsonArray = jsonObject.getJSONArray("Shoe2");
for(int i =0 ; i<jsonArray.length();++i) {
JSONObject rec = jsonArray.getJSONObject(i);
barcode = rec.getString("BarcodeId");
material=rec.getString("Material");
category=rec.getString("Category");
}
Baroode.setText(barcode);
Material.setText(material);
Category.setText(category);
Now what I need is get JSON arrayname "SHoes1" by itself rather than use explicit naming as I am doing so.
My JSON String looks like this
{
"Shoe2":[{
"BarcodeId" : "9770012345673",
" " : "Men",
"Material" : "Panther",
"ProductId" : "ND-TR-0089",
"ProductName" : "Black Retro"
}
]
}
Help will be appreciated :)
Lets assume you have your json in a file name test.json. If you have your array as first element of your root json you can access it via the code below :
package yourPackage;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws IOException {
String metadata = new String(Files.readAllBytes(Paths.get("test.json")));
JSONObject jsonObject = new JSONObject(metadata);
JSONArray jsonArray = jsonObject.getJSONArray(jsonObject.keys().next().toString());
System.out.println(jsonArray.getJSONObject(0));
}
}
Output :
{" ":"Men","ProductName":"Black Retro","Material":"Panther","ProductId":"ND-TR-0089","BarcodeId":"9770012345673"}
test.json :
{
"Shoe2":[{
"BarcodeId" : "9770012345673",
" " : "Men",
"Material" : "Panther",
"ProductId" : "ND-TR-0089",
"ProductName" : "Black Retro"
}
]
}

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

Regex for entire words

I need some help creating a regex. The String value is:
{"meta":[{"this_id":"111111"},{"this_id":"222222"},{"this_id":"333333"}],"type":"Account"}
I want to create a list with all the ids, so element[0] would be 111111, element[1] would be 222222, for example. I would also like to at least be able to isolate the type and set that to a String.
Can I receive some help on this? I tried to do
String[] tokens = stringToBreakUp.split(":");
Then I was just focused on all the tokens after the 2nd element in that list. I am not sure how to search list based on a key. I think I need some sort of key. But I am new at doing these things.
Just use \\d+ to get all the numbers. Check demo
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(yourString);
while (m.find()) {
// print m.group() to get all ids
}
Use any JSON parsing library such as GSON or Jackson and convert it into Java Object.
Sample code using GSON library:
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(jsonString, type);
// just iterate the map and get the desired value
Sample code using Jackson library:
JSONObject obj = new JSONObject(s);
JSONArray jsonArray = obj.getJSONArray("meta");
for (int i = 0; i < jsonArray.length(); i++) {
System.out.println(jsonArray.getJSONObject(i).get("this_id"));
}
output:
111111
222222
333333
I absolutely agree that the RegEx is not an appropriate tool to parse JSON, but this simple test will help you to do it.
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.testng.Assert.assertEquals;
public class SimpleTest {
#Test
public void test() throws Exception {
String str = "{\"meta\":[{\"this_id\":\"111111\"},{\"this_id\":\"222222\"},{\"this_id\":\"333333\"}],\"type\":\"Account\"}";
Pattern idPattern = Pattern.compile("\\{\"this_id\"\\s*\\:\\s*\"(\\d+)\"\\}");
Matcher idMatcher = idPattern.matcher(str);
Collection<String> ids = new ArrayList<>();
while (idMatcher.find()) {
ids.add(idMatcher.group(1));
}
assertEquals(Arrays.asList("111111", "222222", "333333"), ids);
Pattern typePattern = Pattern.compile("\"type\"\\s*\\:\\s*\"([^\"]+)\"");
Matcher typeMatcher = typePattern.matcher(str);
String type = typeMatcher.find() ? typeMatcher.group(1) : null;
assertEquals("Account", type);
}
}

Categories

Resources