I am using something like this-
String Number1=to_1;
String Number2=to_2;
String[] arrayNumbers = new String[] {(char)34+Number1+(char)34,(char)34+Number2+(char)34};
System.out.println(Arrays.toString(arrayNumbers));
JSONObject jsonObj = new JSONObject();
jsonObj.put("to",Arrays.toString(arrayNumbers));
jsonObj.put("type",type);
jsonObj.put("callback",callbackUrl);
JSONArray array = new JSONArray();
JSONObject Array_item = new JSONObject();
jsonObj.put(type, array);
Array_item.put("caption",captionName);
array.add(Array_item);
System.out.println(jsonObj.toString());
Expected-
{
"to":["91890xx", "91890xx"],
"type": "document", "document" : {"caption" : "doc"},
"callback":"{{callback}}"
}
Actual- {"document":[{"caption":"hello"}],"callback":"{{callback}}","to":"[\"91890xxx\", \"91890xx\"]","type":"document"}
I don't know any more logic to remove the out double quotes of to number where as its considering that to a string where as both the numbers should be array format as mentioned in Expected.
First, I show you the correct codes:
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Test {
/**
* <pre>
* {
* "to":["91890xx", "91890xx"],
* "type": "document",
* "document" : {"caption" : "doc"},
* "callback":"{{callback}}"
* }
* </pre>
*
* #param args
* #throws JSONException
*/
public static void main(String[] args) throws JSONException {
String number1 = "91890";
String number2 = "91890";
String[] numbers = new String[]{number1, number2};
JSONArray toNode = new JSONArray();
for (String number : numbers) {
toNode.put(number);
}
JSONObject jsonObj = new JSONObject();
jsonObj.put("to", toNode);
jsonObj.put("type", "document");
jsonObj.put("document", new JSONObject().put("caption", "doc"));
jsonObj.put("callback", "{{callback}}");
System.out.println(jsonObj.toString());
}
}
Result:
{"document":{"caption":"doc"},"callback":"{{callback}}","to":["91890","91890"],"type":"document"}
If you want create a josn array node, you show use JSONArray, and use JSONArray#put(*) method to add elements.
Put string into JSONArray or JSONObject, you don't need wrap the string with quote("). Besides, you should write \" instead of (char) 34 which is a little obscure in Java.
The following case is used to reply comments.
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URL;
import java.util.*;
public class Test1 {
public static void main(String[] args) throws JSONException {
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", new Date());
map.put("key3", 1);
map.put("key4", null);
map.put("key5", Collections.singletonMap("key5-key1", "value"));
map.put("key6", Arrays.asList(1, 2, 3, 4));
map.put("key7", BigDecimal.TEN);
map.put("key8", new String[]{"a", "b", "c"});
map.put("key9", TestEnum.A);
map.put("key10", new TestEnum[]{TestEnum.A, TestEnum.B, TestEnum.C});
Object json = buildJsonObj(map);
System.out.println(json);
}
private static Object buildJsonObj(Object source) throws JSONException {
if (source == null) {
return null;
}
if (isSimpleValueType(source.getClass())) {
return source;
}
if (source instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) source;
JSONObject jsonObject = new JSONObject();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
if (!(key instanceof String)) {
throw new IllegalArgumentException("key must be string.");
}
jsonObject.put((String) key, buildJsonObj(entry.getValue()));
}
return jsonObject;
}
if (source instanceof Iterable) {
Iterable<Object> iterable = (Iterable<Object>) source;
JSONArray jsonArray = new JSONArray();
for (Object value : iterable) {
jsonArray.put(buildJsonObj(value));
}
return jsonArray;
}
if (source.getClass().isArray()) {
Object[] array = (Object[]) source;
JSONArray jsonArray = new JSONArray();
for (Object value : array) {
jsonArray.put(buildJsonObj(value));
}
return jsonArray;
}
throw new IllegalArgumentException("Unsupported type: " + source + ".");
}
private static boolean isSimpleValueType(Class<?> clazz) {
return (Enum.class.isAssignableFrom(clazz) ||
CharSequence.class.isAssignableFrom(clazz) ||
Number.class.isAssignableFrom(clazz) ||
Date.class.isAssignableFrom(clazz) ||
URI.class == clazz || URL.class == clazz ||
Locale.class == clazz);
}
public enum TestEnum {
A, B, C
}
}
Result:
{"key1":"value1","key2":"Thu Mar 14 20:20:49 CST 2019","key5":{"key5-key1":"value"},"key6":[1,2,3,4],"key3":1,"key9":"A","key7":10,"key8":["a","b","c"],"key10":["A","B","C"]}
Replace line
jsonObj.put("to",Arrays.toString(arrayNumbers));
to
jsonObj.put("to", Arrays.asList(arrayNumbers));
Your value is String of 'to',so can you please convert string to json after that you can convert json to array.
Replace
jsonObj.put("to",Arrays.toString(arrayNumbers));
With
jsonObj.put("to",arrayNumbers);
let a = {"document":[{"caption":"hello"}],"callback":"{{callback}}","to":"[\"91890xxx\", \"91890xx\"]","type":"document"};
a = JSON.parse(JSON.stringify(a));
let b = JSON.parse(a.to);
a.to = b;
console.log(a);
This is the exact structure of you required json.
{
"to": ["91890xx", "91890xx"],
"type": "document",
"document": {
"caption": "doc"
},
"callback": "{{callback}}"
}
To Remove the double quotes, please use replace function as shown below
String Number1="[\"91890xxx\", \"91890xx\"]";
Number1.replace("\\/", "");
System.out.println("Excepted output:"+Number1);
output:
Excepted output:["91890xxx", "91890xx"]
Related
I am having the following sample from a JSON file:
[
{
"0":
{
"File":"file1.java",
"Class":"com.ETransitionActionType",
"Method":"values",
"Annotation":"Not Found"
}
},
{
"1":
{
"File":"file2.java",
"Class":"com.ETransitionParams",
"Method":"values",
"Annotation":"Not Found"
}
},
{
"2":
{
"File":"file3.java",
"Class":"com.phloc.commons.id.IHasID",
"Method":"getID",
"Annotation":"Not Found"
}
},
{
"4":
{
"File":"file3.java",
"Class":"com.ExecuteTransitionActionHandler",
"Method":"createBadRequestResponse",
"Annotation":"Not Found"
}
},
{
"5":
{
"File":"file3.java",
"Class":"com.ExecuteTransitionActionHandler",
"Method":"extractParametersFromAction",
"Annotation":"Not Found"
}
}]
How can I restructure this file using java so that it looks like:
[{
"file1.java": {
"com.ETransitionActionType": {
"values": {
"Annotation": "Not Found"
}
}
}
},
{
"file2.java": {
"com.ETransitionParams": {
"values": {
"Annotation": "Not Found"
}
}
}
},
{
"file3.java": {
"com.phloc.commons.id.IHasID": {
"getID": {
"Annotation": "Not Found"
}
},
"com.ExecuteTransitionActionHandler": {
"getID": {
"Annotation": "Not Found"
},
"extractParametersFromAction": {
"Annotation": "Not Found"
}
}
}
}
]
i.e. Going through the JSON file, searching it, and wherever the "File" attribute has the same value("file3.java" for example), we list all the relevant classes and methods inside and the same applies for the "Class" attribute, if it has the same name, we list all the methods inside it(So it's like comparing and sorting the values for the "File" and "Class" attributes).
I started with JSON simple library and wrote like the code below, but don't know how to go further!
Object object = (JSONArray)parser.parse(new FileReader("rawOutput.json"));
JSONArray jsonArray = (JSONArray) object;
for(int i = 0; i < jsonArray.size(); i++) {
System.out.println(jsonArray.get(i));
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
String c = jsonObject.get("" + i + "").toString();
}
Any ideas? Your help is really appreciated!!!
I wrote a code to do what do you need but first you have to add this library to your project if you don't have already org.json.zip library, because I didn't have a library for parsing Json texts so I used this library for formatting the Json data, and I'm sorry if you don't understand the code completely because your request isn't so easy as yourself know and I created three functions to get the result and although I wrote some comments to understand easily, this is the code:-
Edit
...
import org.json.*;
...
...
public static void main(String[] args) throws JSONException {
System.out.println(getFormattedJson("json text"));
}
private static String getFormattedJson(String text) throws JSONException{
JSONArray result = new JSONArray();
JSONArray jsonArray = null;
//get the json array
jsonArray = new JSONArray(text);
//loop through items in the array and insert them formatted to the result
for (int i = 0; i < jsonArray.length(); i++) {
//get object inside the number
JSONObject object = getJsonChild(jsonArray.getJSONObject(i));
//get these attributes
String file = object.getString("File");
String clas = object.getString("Class");
String meth = object.getString("Method");
String anno = object.getString("Annotation");
//create a custom type of the object's attributes
Map<String, String> map = new HashMap<>();
map.put("Annotation", anno);
Map<String, Object> map1 = new HashMap<>();
map1.put(meth, map);
Map<String, Object> map2 = new HashMap<>();
map2.put(clas, map1);
Map<String, Object> map3 = new HashMap<>();
map3.put(file, map2);
//loop through repeating values to also add them to one value as you expected
for (int j = jsonArray.length() - 1; j > i; j--) {
JSONObject obj = getJsonChild(jsonArray.getJSONObject(j));
String file1 = obj.getString("File");
String clas1 = obj.getString("Class");
String meth1 = obj.getString("Method");
String anno1 = obj.getString("Annotation");
if (file1.equals(file)) {
if (map2.containsKey(clas1)) {
if (childrenContains(map2, meth1)) {
//if the difference was annotation value
map.put("Annotation", anno1);
} else {
//if the difference was method names
Map<String, String> map_ = new HashMap<>();
map_.put("Annotation", anno1);
((Map<String, Object>) map2.get(clas1)).put(meth1, map_);
}
} else {
//if the difference was class names
Map<String, String> map_ = new HashMap<>();
map_.put("Annotation", anno1);
Map<String, Object> map1_ = new HashMap<>();
map1_.put(meth1, map_);
map2.put(clas1, map1_);
}
//remove the (value added) object
jsonArray.remove(j);
}
}
//add the map to the result
result.put(map3);
}
return result.toString(4);
}
private static boolean childrenContains(Map<String, Object> map1, String meth1) {
for (String childKey : map1.keySet()) {
Map<String, Object> child = (Map<String, Object>) map1.get(childKey);
if (child.containsKey(meth1))
return true;
}
return false;
}
private static JSONObject getJsonChild(JSONObject object) throws JSONException {
Iterator<String> keys = object.keys();
String key = "";
while (keys.hasNext()) {
key = (String) keys.next();
}
return object.getJSONObject(key);
}
And the result for your sample using my code is:-
[
{"file1.java": {"com.ETransitionActionType": {"values": {"Annotation": "Not Found"}}}},
{"file2.java": {"com.ETransitionParams": {"values": {"Annotation": "Not Found"}}}},
{"file3.java": {
"com.ExecuteTransitionActionHandler": {
"createBadRequestResponse": {"Annotation": "Not Found"},
"extractParametersFromAction": {"Annotation": "Not Found"}
},
"com.phloc.commons.id.IHasID": {"getID": {"Annotation": "Not Found"}}
}}
]
And if you want to get the json data from a file so use the following function to create the JSONArray easily:-
private static JSONArray readFromFile(String filePath){
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
return new JSONArray(sb.toString());
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
And use it instead the text json data:-
...
//get the json array
jsonArray = readFromFile("FilePath");
...
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Foo {
public static void main(String... args) throws IOException {
String json = formatJson(new FileReader("rawOutput.json"));
System.out.println(json);
}
public static String formatJson(Reader reader) throws IOException {
// group array items by fileName
final Function<List<Map<String, Object>>, Map<String, List<Object>>> groupByFileName =
data -> data.stream().collect(Collectors.groupingBy(map -> (String)map.get("File"), TreeMap::new,
Collectors.mapping(Function.identity(), Collectors.toList())));
// convert source item structure into required
final Function<Map.Entry<String, List<Object>>, Map<String, Object>> convert = entry -> {
Map<String, Map<String, Map<String, String>>> tmp = new LinkedHashMap<>();
entry.getValue().stream()
.map(value -> (Map<String, String>)value)
.forEach(map -> {
Map<String, Map<String, String>> classes = tmp.computeIfAbsent(map.get("Class"), cls -> new TreeMap<>());
Map<String, String> methods = classes.computeIfAbsent(map.get("Method"), method -> new TreeMap<>());
map.entrySet().stream()
.filter(e -> !"Class".equals(e.getKey()) && !"Method".equals(e.getKey()) && !"File".equals(e.getKey()))
.forEach(e -> methods.put(e.getKey(), e.getValue()));
});
return Collections.singletonMap(entry.getKey(), tmp);
};
ObjectMapper mapper = new ObjectMapper();
// read json as array of Maps
List<Map<String, Object>> data = Arrays.stream(mapper.readValue(reader, Map[].class))
.map(map -> map.values().iterator().next())
.map(item -> (Map<String, Object>)item)
.collect(Collectors.toList());
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(groupByFileName.apply(data).entrySet().stream()
.map(convert).collect(Collectors.toList()));
}
}
You could create a map of maps to represent your grouping by "File" and "Class" for your list of (inner) JSON objects. It might look similar to
final Function<JSONObject, String> fileFunction = (JSONObject jsonObject) -> jsonObject.getString("File");
final Function<JSONObject, String> classFunction = (JSONObject jsonObject) -> jsonObject.getString("Class");
final Map<String, Map<String, List<JSONObject>>> groupedJsonObjects = jsonObjects.stream()
.collect(Collectors.groupingBy(fileFunction, Collectors.groupingBy(classFunction)));
I want to create org.json.JSONObject from String.
the String is "user.phone.num : 00113". the result that i would like to have is org.json.JSONObject object with this format:
{
user:
{
phone: {num: 00113}
}
}
so is there any built in method to achieve this result. Thanks.
if every line of your json is splitted yo can try this code
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by ebi on 7/3/17.
*/
public class Main {
public static void main(String[] args) throws JSONException {
String str = "user.phone.num : 00113";
String json_str = str_to_json(str);
JSONObject jsonObject = new JSONObject(json_str);
System.out.println(jsonObject);
}
public static String str_to_json(String jsonByDot){
int valOffset = jsonByDot.indexOf(":");
String keys = jsonByDot.substring(0,valOffset).trim();
String val = jsonByDot.substring(valOffset+1).trim();
String keysArr[] = keys.split("\\.");
String output = "";
for(String key:keysArr){
output+="{"+key+":";
}
output+=val;
for (int i = 0 ;i<keysArr.length;i++){
output+="}";
}
return output;
}
}
Try using below -
JSONObject obj1 = new JSONObject();
obj1.put("birthdate", "01-01-2017");
obj1.put("age", new Integer(18));
JSONObject obj2 = new JSONObject();
obj2.put("name", "abc");
obj2.put("details", obj1);
I am trying to parse the content of JSON file text.json by using Jackson library.
What I want is to make a java method to get all keys and values of it, but so far in my code I get only the first key and the first value of the JSON file.
The code snippet I used as guidance to make my own Java class is the following:
public void parse(String json) {
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode = mapper.readTree(json);
Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String,JsonNode> field = fieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
}
And my Java class that I created is shown below:
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
public class JacksonStreamExample {
public static void main(String[] args) {
try {
//Create a JsonFactory instance
JsonFactory factory = new JsonFactory();
//Create a JsonParser instance to read from file c:\\text.json
JsonParser jParser = factory.createJsonParser(new File("c:\\text.json"));
/*Create an ObjectMapper instance to provide a pointer
* to root node of the tree after reading the JSON
*/
ObjectMapper mapper = new ObjectMapper(factory);
//Create tree from JSON
JsonNode rootNode = mapper.readTree(jParser);
Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.getFields();
while (fieldsIterator.hasNext()) {
Map.Entry<String,JsonNode> field = fieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
jParser.close();
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
My Eclipse output is the following which creates only 1 pair(key-value):
Key: cells Value:[{"type":"basic.Circle","size":{"width":90,"height":54},"position":{"x":-80,"y":200},"angle":0,"id":"cae4c219-c2cd-4a4b-b50c-0f269963ca24","embeds":"","z":1,"wi_name":"START","wi_displayName":"START","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"circle":{"fill":"#000000","width":50,"height":30,"stroke-width":1,"stroke-dasharray":"0"},"text":{"font-size":10,"text":"START","fill":"#ffffff","font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"basic.Circle","size":{"width":90,"height":54},"position":{"x":210,"y":200},"angle":0,"id":"d23133e0-e516-4f72-8127-292545d3d479","embeds":"","z":2,"wi_name":"END","wi_displayName":"END","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"circle":{"fill":"#000000","width":50,"height":30,"stroke-width":1,"stroke-dasharray":"0"},"text":{"font-size":10,"text":"END","fill":"#ffffff","font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"basic.Rect","position":{"x":-80,"y":370},"size":{"width":90,"height":54},"angle":0,"id":"a53898a5-c018-45c4-bd3f-4ea4d69f58ed","embeds":"","z":3,"wi_name":"ACTIVITY_1","wi_displayName":"ACTIVITY 1","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"rect":{"width":50,"height":30,"rx":2,"ry":2,"stroke-width":1,"stroke-dasharray":"0"},"text":{"text":"Activity","font-size":10,"font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"basic.Rect","position":{"x":220,"y":370},"size":{"width":90,"height":54},"angle":0,"id":"e2bd21f2-508d-44b9-9f68-e374d4fa87ea","embeds":"","z":4,"wi_name":"ACTIVITY_2","wi_displayName":"ACTIVITY 2","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"rect":{"width":50,"height":30,"rx":2,"ry":2,"stroke-width":1,"stroke-dasharray":"0"},"text":{"text":"Workitem","font-size":10,"font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"link","source":{"id":"cae4c219-c2cd-4a4b-b50c-0f269963ca24"},"target":{"id":"d23133e0-e516-4f72-8127-292545d3d479"},"router":{"name":"manhattan"},"labels":[{"position":0.5,"attrs":{"text":{"text":"Name"}}}],"id":"60ee7ff7-3a3b-487d-b581-49027e7bebe4","embeds":"","z":5,"attrs":{".marker-source":{"d":"M 10 0 L 0 5 L 10 10 z","transform":"scale(0.001)"},".marker-target":{"d":"M 10 0 L 0 5 L 10 10 z"},".connection":{"stroke":"black"}}},{"type":"link","source":{"id":"a53898a5-c018-45c4-bd3f-4ea4d69f58ed"},"target":{"id":"e2bd21f2-508d-44b9-9f68-e374d4fa87ea"},"router":{"name":"manhattan"},"labels":[{"position":0.5,"attrs":{"text":{"text":"Name"}}}],"id":"cea0d1c2-2c18-4bd7-ba35-d94918c6fc9b","embeds":"","z":6,"attrs":{".marker-source":{"d":"M 10 0 L 0 5 L 10 10 z","transform":"scale(0.001)"},".marker-target":{"d":"M 10 0 L 0 5 L 10 10 z"},".connection":{"stroke":"black"}}}]
I just need to make a method to put this code inside to get all key-value pairs:
//Create a JsonFactory instance
JsonFactory factory = new JsonFactory();
//Create a JsonParser instance to read from file c:\\text.json
JsonParser jParser = factory.createJsonParser(new File("c:\\text.json"));
/*Create an ObjectMapper instance to provide a pointer
*to root node of the tree after reading the JSON
*/
ObjectMapper mapper = new ObjectMapper(factory);
//Create tree from JSON
JsonNode rootNode = mapper.readTree(jParser);
Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.getFields();
while (fieldsIterator.hasNext()) {
Map.Entry<String,JsonNode> field = fieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
How will I do it please?
You should use Jackson2 instead of Jackson1. As the error message specifies, Jackson1's JsonNode indeed does not have this fields() method, while Jackson2's version does.
In Jackson1, you would have to do something like this:
Iterator<String> fieldNameIterator = rootNode.getFieldNames();
while (fieldNameIterator.hasNext()) {
String fieldName = fieldNameIterator.next();
JsonNode fieldValue = rootNode.getFieldValue(fieldName);
System.out.println("Key: " + fieldName + "\tValue:" + fieldValue);
}
I solved my problem by changing JSON library.
I used json-simple-1.1.1
My final code that worked is the following:
package jsontoxml;
import java.io.*;
import org.json.simple.parser.JSONParser;
import org.json.simple.*;
import java.util.*;
public class JacksonStreamExample {
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("text.json"));
JSONObject jsonObject = (JSONObject) obj;
JSONArray cells = (JSONArray) jsonObject.get("cells");
Iterator<JSONObject> iterator = cells.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now that you have modified the question and json, here is the solution you're looking for:
public static void main(String[] args) {
try {
Map source = (new ObjectMapper()).readValue(new File(
"C:\\json.txt"), Map.class);
Map<String, Object> result = new LinkedHashMap<>();
buildFlattenedMap(result, source, null);
for (String s : result.keySet()) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void buildFlattenedMap(Map<String, Object> result,
Map<String, Object> source, String path) {
for (Map.Entry<String, Object> entry : source.entrySet()) {
String key = entry.getKey();
if (hasText(path)) {
if (key.charAt(0) == '[') {
key = StringUtils.join(path, key);
} else {
key = StringUtils.join(path, '.', key);
}
}
Object value = entry.getValue();
if (value instanceof String) {
result.put(key, value);
} else if (value instanceof Map) {
// Need a compound key
#SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) value;
buildFlattenedMap(result, map, key);
} else if (value instanceof Collection) {
// Need a compound key
#SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) value;
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap("["
+ (count++) + "]", object), key);
}
} else {
result.put(key, value == null ? StringUtils.EMPTY : value);
}
}
}
private static boolean hasText(CharSequence str) {
if (StringUtils.isEmpty(str)) {
return false;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
FYI, buildFlattenedMap method is actually from spring framework which I had used recently for processing a similar stuff.
https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java
I would like to mask certain elements of JSON and print to logs. Masking can be either by substituting by dummy data or removing the key pair .Is there a utility to do the masking in Java ?
E.g.,
given JSON:
{
"key1":"value1",
"key2":"value2",
"key3":"value3",
}
mask key 2 alone and print JSON:
{
"key1":"value1",
"key2":"xxxxxx",
"key3":"value3",
}
or
{
"key1":"value1",
"key3":"value3",
}
input will be JSON object or array type in string format. Here the maskable keys only static otherwise input string will dynamic.
public final class MaskPIData {
/**
* Mask able keywords mentioned here. It should be in LOWER CASE.
*/
private static final Set<String> MASKABLE_KEYS = new HashSet<>(Arrays.asList(
"email",
"emails",
"phone",
"pin",
"password",
"phonenumber",
"moneys"));
private static final String MASKING_VALUE = "****";
private static final ObjectMapper OBJECTMAPPER = new ObjectMapper();
private MaskPIData() {
super();
}
private static boolean isValidSet(Set<String> set) {
return set != null && !set.isEmpty();
}
private static boolean isKnownPrimitiveWrapperModel(Object obj) {
return obj == null || obj instanceof String || obj instanceof Integer || obj instanceof Long
|| obj instanceof Double;
}
#SuppressWarnings("unchecked")
private static JSONObject maskingForJsonObject(Set<String> maskableKeys, JSONObject input) {
if (!isValidSet(maskableKeys) || input == null) {
return input;
}
Map<String, Object> inputMap = (Map<String, Object>) input;
Map<String, Object> caseInsensitiveInputMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
caseInsensitiveInputMap.putAll(inputMap);
for (Map.Entry<String, Object> entryPair : caseInsensitiveInputMap.entrySet()) {
if (entryPair.getValue() instanceof JSONArray) {
JSONArray jsonArr = (JSONArray) caseInsensitiveInputMap.get(entryPair.getKey());
maskingForArray(maskableKeys, entryPair.getKey(), jsonArr);
caseInsensitiveInputMap.put(entryPair.getKey(), jsonArr);
} else if (entryPair.getValue() instanceof JSONObject) {
JSONObject jsonObj = (JSONObject) caseInsensitiveInputMap.get(entryPair.getKey());
caseInsensitiveInputMap.put(entryPair.getKey(), maskingForJsonObject(maskableKeys, jsonObj));
} else if (entryPair.getKey() != null && maskableKeys.contains(entryPair.getKey().toLowerCase())) {
caseInsensitiveInputMap.put(entryPair.getKey(), MASKING_VALUE);
}
}
return OBJECTMAPPER.convertValue(caseInsensitiveInputMap, JSONObject.class);
}
#SuppressWarnings("unchecked")
private static JSONArray maskingForArray(Set<String> maskableKeys, String key,
JSONArray jsonArr) {
JSONArray toRet = jsonArr;
for (int idx = 0; idx < toRet.size(); idx++) {
Object obj = toRet.get(idx);
if (isKnownPrimitiveWrapperModel(obj)) {
if (key != null && maskableKeys.contains(key.toLowerCase())) {
toRet.remove(idx);
toRet.add(idx, MASKING_VALUE);
}
} else {
JSONObject jsonObjFromArray = (JSONObject) toRet.get(idx);
JSONObject maskedJsonObj = maskingForJsonObject(maskableKeys, jsonObjFromArray);
toRet.remove(idx);
toRet.add(idx, maskedJsonObj);
}
}
return toRet;
}
public static String doMask(String input) {
String maskedData = input;
if (maskedData != null && !maskedData.trim().isEmpty()) {
try {
if (new JSONParser().parse(maskedData) instanceof JSONObject) {
JSONObject maskedOutput = maskingForJsonObject(MASKABLE_KEYS,
(JSONObject) new JSONParser().parse(maskedData));
maskedData = OBJECTMAPPER.writeValueAsString(maskedOutput);
} else if (new JSONParser().parse(maskedData) instanceof JSONArray) {
JSONArray maskedOutput = maskingForArray(MASKABLE_KEYS, null, (JSONArray) new JSONParser().parse(maskedData));
maskedData = OBJECTMAPPER.writeValueAsString(maskedOutput);
}
} catch (Exception e) {
// to do - Error while masking data
}
}
return maskedData;
}
public static void main(String args[]) {
String input = "{\"item\":{\"test\":\"test\",\"phone\":\"993244\",\"email\":\"mail#mail.com\"}}";
System.out.println(doMask(input));
}
You could use jackson to convert json to map, process map and convert map back to json.
For example:
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public void mask() throws IOException {
String jsonString = "{\n" +
" \"key1\":\"value1\",\n" +
" \"key2\":\"value2\",\n" +
" \"key3\":\"value3\"\n" +
"}";
Map<String, Object> map;
// Convert json to map
ObjectMapper mapper = new ObjectMapper();
try {
TypeReference ref = new TypeReference<Map<String, Object>>() { };
map = mapper.readValue(jsonString, ref);
} catch (IOException e) {
System.out.print("cannot create Map from json" + e.getMessage());
throw e;
}
// Process map
if(map.containsKey("key2")) {
map.put("key2","xxxxxxxxx");
}
// Convert back map to json
String jsonResult = "";
try {
jsonResult = mapper.writeValueAsString(map);
} catch (IOException e) {
System.out.print("cannot create json from Map" + e.getMessage());
}
System.out.print(jsonResult);
This is the program i wrote:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication1;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
/**
*
* #author 311001
*/
public class NewClass {
public static void main(String args[]) {
JSONObject parentData = new JSONObject();
JSONObject childData = new JSONObject();
try {
parentData.put("command", "login");
parentData.put("uid", "123123123");
childData.put("uid", "007");
childData.put("username", "sup");
childData.put("password", "bros");
parentData.put("params", childData);
System.out.println(parentData);
Map<String, String> map = new HashMap<>();
Iterator<?> iter = parentData.keys();
while (iter.hasNext()) {
String key = (String) iter.next();
String value = parentData.getString(key);
map.put(key, value);
}
for (Entry<String, String> entry : map.entrySet()) {
System.out.println("key > " + entry.getKey() + " : value = " + entry.getValue());
}
String testData = map.get("params.uid");
System.out.println(testData);
System.out.println("Tokenizing json");
String resultStr = parentData.toString();
System.out.println("String tokens ");
StringTokenizer st = new StringTokenizer(resultStr);
System.out.println(st.countTokens());
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
String testDat="abc :: result";
StringTokenizer simpleString = new StringTokenizer(testDat);
System.out.println("Tokenizing simple string");
System.out.println(simpleString.countTokens());
while (simpleString.hasMoreTokens()) {
System.out.println(simpleString.nextToken());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
the output i got:
run:
{"command":"login","uid":"123123123","params":{"uid":"007","username":"sup","password":"bros"}}
key > uid : value = 123123123
key > command : value = login
key > params : value = {"uid":"007","username":"sup","password":"bros"}
null
Tokenizing json
String tokens
1
{"command":"login","uid":"123123123","params":{"uid":"007","username":"sup","password":"bros"}}
Tokenizing simple string
3
abc
::
result
BUILD SUCCESSFUL (total time: 0 seconds)
How can I recieve all the keys in my json object. In case I tokenize why do i get only one string token while for a simple string am getting the correct output 3 tokens.
You can recursively traverse your JsonObject to get all keys.
heres the pseudocode
findKeys(JsonObject obj,List keys){
List<String>keysFromObj=obj.keys();
keys.addAll(keysFromObj);
for(String key:keysFromObj){
if(obj.get(key).getClass()==JSONObject.class){
findKeys(obj.get(key),keys);
}
}
}
So suppose if your object is {"a":1,"b":{"c":"hello","d":4.0}}
the above function should give you ["a","b","c","d"]
But if you want only ["a","c","d"] as your output,you can write-
findKeys(JsonObject obj,List keys){
List<String>keysFromObj=obj.keys();
for(String key:keysFromObj){
if(obj.get(key).getClass()==JSONObject.class){
findKeys(obj.get(key),keys);
}else{
keys.add(key);
}
}
}
I am late to the party, but I am adding here my solution:
Input:
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
Retrieve all unique keys:
public static void findAllKeys(Object object, Set<String> finalKeys) {
if (object instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) object;
jsonObject.keySet().forEach(childKey -> {
finalKeys.add(childKey);
findAllKeys(jsonObject.get(childKey), finalKeys);
});
} else if (object instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) object;
IntStream.range(0, jsonArray.length())
.mapToObj(jsonArray::get)
.forEach(o -> findAllKeys(o, finalKeys));
}
}
Usage:
Set<String> finalKeys = new HashSet<>();
findAllKeys(new JSONObject(str), finalKeys);
System.out.println(finalKeys);
Output:
[
GlossEntry,
GlossSee,
SortAs,
GlossList,
title,
GlossDiv,
glossary,
GlossTerm,
GlossDef,
para,
GlossSeeAlso,
ID,
Acronym,
Abbrev
]
Retrieve all unique "full path" keys:
public void findAllKeys(Object object, String key, Set<String> finalKeys) {
if (object instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) object;
jsonObject.keySet().forEach(childKey -> {
findAllKeys(jsonObject.get(childKey), key != null ? key + "." + childKey : childKey, finalKeys);
});
} else if (object instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) object;
finalKeys.add(key);
IntStream.range(0, jsonArray.length())
.mapToObj(jsonArray::get)
.forEach(jsonObject -> findAllKeys(jsonObject, key, finalKeys));
}
else{
finalKeys.add(key);
}
}
Usage:
Set<String> finalKeys = new HashSet<>();
findAllKeys(new JSONObject(jsonStr), null, finalKeys);
System.out.println(finalKeys);
Output:
[
glossary.GlossDiv.GlossList.GlossEntry.ID,
glossary.title,
glossary.GlossDiv.GlossList.GlossEntry.GlossSee,
glossary.GlossDiv.GlossList.GlossEntry.GlossTerm,
glossary.GlossDiv.GlossList.GlossEntry.Acronym,
glossary.GlossDiv.GlossList.GlossEntry.Abbrev,
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para,
glossary.GlossDiv.GlossList.GlossEntry.SortAs,
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso,
glossary.GlossDiv.title
]
Here is one implementation using org.json not org.json.simple
It finds all unique values of a json with the Key:value combination using java.
Input json:
{
d: {
results: [{
__metadata: {
uri:https://google.com,
type: User
},
userId: jmarthens1,
businessPhone: null,
salaryProrating: null,
empId: 2023,
lastModifiedDateTime: Date(1458308558000 + 0000),
finalJobRole: null,
username: jmarthens,
married: false,
futureLeader: null,
salary: 79000.0,
jobRole: Program Manager,
Professional Services,
nickname: null,
salaryLocal: null
}]
}
}
Result:
empId-2023
lastModifiedDateTime-Date(1458308558000+0000)
salary-79000.0
userId-jmarthens1
jobRole-Program Manager, Professional Services
type-User
uri-https://google.com
username-jmarthens
Code:
package test;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TestClass {
private static StringBuilder strOut = new StringBuilder();
public static void main(String[] args) {
try {
String json = "{\"d\" : {\"results\" : [{\"__metadata\" : {\"uri\" : \"https://apisalesdemo8.successfactors.com:443/odata/v2/User('jmarthens1')\","
+ " \"type\" : \"SFOData.User\"}, \"userId\" : \"jmarthens1\", \"businessPhone\" : null, \"salaryProrating\" : null, \"empId\" : \"2023\", "
+ "\"lastModifiedDateTime\" : \"Date(1458308558000+0000)\", \"finalJobRole\" : null, \"username\" : \"jmarthens\", \"married\" : false, "
+ "\"futureLeader\" : null, \"salary\" : \"79000.0\", \"jobRole\" : \"Program Manager, Professional Services\", \"nickname\" : null, \"salaryLocal\" : null}]}}";
JSONObject inputJson = new JSONObject(json);
List<String> lst = new ArrayList<String>();
lst = findKeysOfJsonObject(inputJson, lst);
try (BufferedWriter writer = new BufferedWriter(new FileWriter("C:\\temp\\temp.txt"))) {
writer.write(strOut.toString());
}
} catch (JSONException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static List<String> findKeysOfJsonArray(JSONArray jsonIn, List<String> keys) {
List<String> keysFromArr = new ArrayList<>();
if (jsonIn != null && jsonIn.length() != 0) {
for (int i = 0; i < jsonIn.length(); i++) {
JSONObject jsonObjIn = jsonIn.getJSONObject(i);
keysFromArr = findKeysOfJsonObject(jsonObjIn, keys);
}
}
return keysFromArr;
}
private static List<String> findKeysOfJsonObject(JSONObject jsonIn, List<String> keys) {
Iterator<String> itr = jsonIn.keys();
List<String> keysFromObj = makeList(itr);
keys.addAll(keysFromObj);
itr = jsonIn.keys();
while (itr.hasNext()) {
String itrStr = itr.next();
// System.out.println("out " + itrStr);
JSONObject jsout = null;
JSONArray jsArr = null;
if (jsonIn.get(itrStr).getClass() == JSONObject.class) {
jsout = jsonIn.getJSONObject(itrStr);
findKeysOfJsonObject(jsout, keys);
} else if (jsonIn.get(itrStr).getClass() == JSONArray.class) {
jsArr = jsonIn.getJSONArray(itrStr);
keys.addAll(findKeysOfJsonArray(jsArr, keys));
} else if (jsonIn.get(itrStr).getClass() == String.class) {
System.out.println(itrStr + "-" + jsonIn.get(itrStr));
strOut.append(itrStr + "," + jsonIn.get(itrStr));
strOut.append(System.lineSeparator());
}
}
return keys;
}
public static List<String> makeList(Iterator<String> iter) {
List<String> list = new ArrayList<String>();
while (iter.hasNext()) {
list.add(iter.next());
}
return list;
}
}
static Set<String> finalListOfKeys = new LinkedHashSet<String>();
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("Absolute path of json file"));
JSONObject jsonObject = (JSONObject) obj;
Set<String> jsonKeys = jsonObject.keySet();
for (String key : jsonKeys) {
Object val = jsonObject.get(key);
if (val instanceof JSONArray) {
JSONArray array = (JSONArray) val;
jsonArray(array, key);
} else if (val instanceof JSONObject) {
JSONObject jsonOb = (JSONObject) val;
jsonObj(jsonOb, key);
} else {
finalListOfKeys.add(key);
System.out.println("Key is : " + key);
}
}
System.out.println("Final List : " + finalListOfKeys);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void jsonObj(JSONObject object, String key2) {
Set<String> innerKeys = object.keySet();
System.out.println("Inner Keys : " + innerKeys);
for (String key : innerKeys) {
System.out.println("Key : " + key);
Object val = object.get(key);
if (val instanceof JSONArray) {
JSONArray array = (JSONArray) val;
jsonArray(array, key2 + "->" + key);
} else if (val instanceof JSONObject) {
JSONObject jsonOb = (JSONObject) val;
jsonObj(jsonOb, key2 + "->" + key);
} else {
finalListOfKeys.add(key2 + "->" + key);
System.out.println("Key is : " + key2 + "->" + key);
}
}
}
public static void jsonArray(JSONArray array, String key) {
if (array.size() == 0) {
finalListOfKeys.add(key);
} else {
for (int i = 0; i < array.size(); i++) {
Object jObject = array.get(i);
if (jObject instanceof JSONObject) {
JSONObject job = (JSONObject) jObject;
System.out.println(job);
jsonObj(job, key);
}
}
}
}