Sort a Groovy flattened JsonSluper object after parsing - java

I have a JSON message that after parsing it w/ the JsonSluper the ordering is messed up. I know the ordering isn't important, but I need to put the message back into ascending order after the message is parsed and flatted into single objects, so I can a build a JsonArray and present the message in the proper asc order.
String test = """[
{
"AF": "test1",
"BE": "test2",
"CD": "test3",
"DC": "test4",
"EB": "test5",
"FA": "test5"
},
{
"AF": "test1",
"BE": "test2",
"CD": "test3",
"DC": "test4",
"EB": "test5",
"FA": "test5"
}
]"""
The parseText produces this:
def json = new groovy.json.JsonSlurper().parseText(test);
[{CD=test3, BE=test2, AF=test1, FA=test5, EB=test5, DC=test4}, {CD=test3,
BE=test2, AF=test1, FA=test5, EB=test5, DC=test4}]
After parsing the json message, I need to pass the flatten json object into a method at which point needs to be sorted in ascending order by the map keys prior to adding to a JSONArray like below.
def json = new groovy.json.JsonSlurper().parseText(test);
for( int c = 0; c < json?.size(); c++ )
doSomething(json[c]);
void doSomething( Object json ){
def jSort= json.????
JSONArray jsonArray = new JSONArray();
jsonArray.add(jSort);
}
​

You can just sort entries before adding them. The following uses collectEntries, which creates LinkedHashMap objects (thus preserving order):
def json = new groovy.json.JsonSlurper().parseText(test);
def sortedJson = json.collect{map -> map.entrySet().sort{it.key}
.collectEntries{[it.key, it.value]}}
sortedJson has this content, which seems to be sorted as required:
[[AF:test1, BE:test2, CD:test3, DC:test4, EB:test5, FA:test5],
[AF:test1, BE:test2, CD:test3, DC:test4, EB:test5, FA:test5]]

Related

Using JsonPath in Java (8) to create/add nodes and arrays

I am trying to create or update a JSON with a new key:value nodes inside a JsonArray.
So far I am able to add simple values using a map of nodes, but I am unable to add an array.
The goal is to create a JSON string with the following values:
{
"curfew": [{
"enabled": true,
"lock_time": "00:00",
"unlock_time": "00:10"
},
{
"enabled": true,
"lock_time": "00:20",
"unlock_time": "00:30"
}]
}
Starting from a new and empty JSON and later adding more values (such as the second "curfew" array).
Map<String, Object> values = ImmutableMap.of(
"enabled", true,
"lock_time", "00:00",
"unlock_time", "00:10");
String emptyJson = "{}"; //empty json
DocumentContext doc = getDocument(emptyJson)
doc.set(JsonPath.compile("$.curfew"), values).jsonString();
So far I am getting this (NOT AN ARRAY)
{
"curfew": {
"enabled": true,
"lock_time": "00:00",
"unlock_time": "05:00"
}
}
Create a List<Map<String, Object>> and then add your map in the list
List<Map<String, Object>> list = new ArrayList<>();
list.add(values);
And set the list in doc
doc.set(JsonPath.compile("$.curfew"), list).jsonString();

Parsing through JSON and selecting multiple items in java

I currently have this JSON:
[
{
"example": "12345678",
"test": "0",
"name": "tom",
"testdata": "",
"testtime": 1531209885613
},
{
"example": "12634346",
"test": "43223452234",
"name": "jerry",
"testdata": "pawenkls",
"testtime": 1531209888196
}
]
I am trying to parse through the array to find a value of "testdata" that matches the value of "testdata" that I have generated, which I am currently doing like so:
JsonArray entries = (JsonArray) new JsonParser().parse(blockchainJson);
JsonElement dataHash = ((JsonObject)entries.get(i)).get("dataHash");
Then I wish to find the value of "example" that is in the same array as the "testdata" with the value "pawenkls".
How do I search for the "example" value that is in the same group as the value of "test data" that I have found?
You need to run through the objects in the array and check the value of the testData field against yours. Then read its example field.
String testData = "pawenkls";
JsonArray entries = (JsonArray) new JsonParser().parse(blockchainJson);
String example = null;
for(JsonElement dataHashElement : entries) {
JsonObject currentObject = dataHashElement.getAsJsonObject();
if(testData.equals(currentObject.get("testdata").getAsString())) {
example = currentObject.get("example").getAsString();
break;
}
}
System.out.println("example: "+example);
This prints out
example: 12634346
Here is a Java 8 version doing the same thing:
String testData = "pawenkls";
JsonObject[] objects = new Gson().fromJson(blockchainJson, JsonObject[].class);
Optional<JsonObject> object = Arrays.stream(objects)
.filter(o -> testData.equals(o.get("testdata").getAsString()))
.findFirst();
String example = null;
if(object.isPresent())
example = object.get().get("example").getAsString();
System.out.println("example: "+example);

Convert JsonArrayString to List<String> or String[]

How to convert a JsonArrayString to List<String> or String[]? I tried to use Gson to covert it, but I failed. Maybe I overlooked some existing methods which can do this? Any other better way to make it or can someone give me some tips?
[
{
"test": "test"
},
{
"test": "test"
},
{
"test": "test",
"test2": "test2",
"test3": [
{
"test": "test"
},
{
"test": "test"
}
]
}
]
I guess you dont know if the value is a JSONObject or a JSONArray. In thise case you may want to use a Map and a Object as Value like this (not tested).
class Model {
private Map<String, Object> test;
}
Take care that you have to validate if the Value is a JSONArray or a JSONObject using (for example):
if (this.getTest().getValue() instanceof JSONObject.class) { ... }
I Finally find the way to resovel:
// Converting JSON String array to Java String array
String jsonStringArray = "[{\"test\":\"test1\"},{\"test\":\"test2\"},{\"test\":\"test3\",\"test2\":[{\"test\":\"test1\"},{\"test\":\"test2\"}]}]";
// creating Gson instance to convert JSON array to Java array
Gson converter = new Gson();
Type type = new TypeToken<List>() {
}.getType();
List list = converter.fromJson(jsonStringArray, type);
// convert List to Array in Java
System.out.println("Java List created from JSON String Array - example");
System.out.println("JSON String Array : " + jsonStringArray);
System.out.println("Java List : " + list);
// let's now convert Java array to JSON array -
String toJson = converter.toJson(list);
System.out.println("Json array created from Java List : " + toJson);
output:
Java List created from JSON String Array - example
JSON String Array : [{"test":"test1"},{"test":"test2"},
{"test":"test3","test2":[{"test":"test1"},{"test":"test2"}]}]
Java List : [{test=test1}, {test=test2}, {test=test3, test2=[{test=test1}, {test=test2}]}]
Json array created from Java List : [{"test":"test1"},{"test":"test2"},{"test":"test3","test2":[{"test":"test1"},{"test":"test2"}]}]

Converting Nested Json files to CSV in java

{
"Employee": [
{
"empMID": "mock:1",
"comments": [],
"col1": "something",
"contact": [{"address":"2400 waterview", "freetext":true}
],
"gender": "male"
},
{
"empMID": "mock:2",
"comments": [],
"col1": "something",
"contact": [{"address":"2200 waterview", "freetext":true}
],
"gender": "female"
}
],
"cola": false,
"colb": false
}
This is how my Json file looks .I m required to convert this json to a csv .(I m trying to convert a multi-dimesional data to 2d).I m using gson for my purpose.I cannot use gson.fromgson() function to object map with a template because it should be generic .
I know we can use CDL to convert jsonarray to csv format but It wont work in my case .
my csv format looks like
Employee*
empMID,comment.$,contact.address,contact.freetext,gender
mock:1,,2400 waterview,TRUE,male
mock:123,,2200 waterview,TRUE,female
colA#
TRUE
colB#
FALSE
I tried using google-GSON api to convert to this format .But I m not able to convert to this format .I have used * to represent its a json array and # to represent its a primitive type and contact.address to represent nested array inside another json array .I having problem relating this nested structure .I m able to traverse everything recursively like a column. Thanks in advance
public static void main(String[] args) throws IOException{
BufferedReader reader=null;
StringBuilder content=null;
String result=null;
reader = new BufferedReader(new FileReader("temp.json"));
String line = null;
content= new StringBuilder();
while ((line = reader.readLine()) != null) {
content.append(line);
}
reader.close();
result= content.toString();
JsonElement jelement = new JsonParser().parse(result);
printJsonRecursive(jelement);
}
public static void printJsonRecursive(JsonElement jelement){
if(jelement.isJsonPrimitive()){
System.out.println(jelement.getAsString());
return;
}
if(jelement.isJsonArray()){
JsonArray jarray= jelement.getAsJsonArray();
for(int i=0;i<jarray.size();i++){
JsonElement element= jarray.get(i);
printJsonRecursive(element);
}
return;
}
JsonObject jobject= jelement.getAsJsonObject();
Set<Entry<String, JsonElement>> set= jobject.entrySet();
for (Entry<String, JsonElement> s : set) {
printJsonRecursive(s.getValue());
}
}
}
You can achieve this thru reflection if you have a object mapped to the json.
use gson/jackson to convert json to java object
append fields using reflection by iterating the class and get any field you interested in.
append value with reflection by getting value from the target object.
More detail look at my blog post below:
vcfvct.wordpress.com/2015/06/30/converting-nested-json-files-to-csv-in-java-with-reflection/
You are not printing the key. This should fix it.
for (Entry<String, JsonElement> s : set) {
System.out.println(s.getKey()); //Added
printJsonRecursive(s.getValue());
}
You can take care of \ns from here.
EDIT
If you want to print the keys just once for repeating json objects, create a Java bean to hold the data and populate it during your recursion. Once the bean is complete, add a method there to print all the data in the format you want (printing keys only once and so on).
You can use the library json2flat for converting your JSON to CSV.
This library doesn't require any POJO's. It simply takes your JSON as string and returns a 2D representation of it in the format of List<Object[]>.
For example for the JSON:
{
"Employee": [
{
"empMID": "mock:1",
"comments": [],
"col1": "something",
"contact": [{"address":"2400 waterview", "freetext":true}
],
"gender": "male"
},
{
"empMID": "mock:2",
"comments": [],
"col1": "something",
"contact": [{"address":"2200 waterview", "freetext":true}
],
"gender": "female"
}
],
"cola": false,
"colb": false
}
It gives an output:
/cola,/colb,/Employee/empMID,/Employee/col1,/Employee/gender,/Employee/contact/address,/Employee/contact/freetext
,,"mock:1","something",,"2400 waterview",true
,,"mock:2","something",,"2200 waterview",true
false,false,,,,,
/**
* Get separated comlumns used a separator (comma, semi column, tab).
*
* #param headers The CSV headers
* #param map Map of key-value pairs contains the header and the value
*
* #return a string composed of columns separated by a specific separator.
*/
private static String getSeperatedColumns(Set<String> headers, Map<String, String> map, String separator) {
List<String> items = new ArrayList<String>();
for (String header : headers) {
String value = map.get(header) == null ? "" : map.get(header).replaceAll("[\\,\\;\\r\\n\\t\\s]+", " ");
items.add(value);
}
return StringUtils.join(items.toArray(), separator);
}

Represent JSON as an array of objects in JAVA

I would like to create a JSON string as an array of objects like this:
[
{
"alertid": "1",
"alerttext": "This is test",
"alertdate": "2010-02-11 09:03:40"
},
{
"alertid": "2",
"alerttext": "Another alert",
"alertdate": "2010-02-11 09:11:04"
}
]
The JAVA JSON objects put method looks like this: jsonObject.put(String key, Collection value);
When I enter my key and collection, my json looks like this:
{
"JSONObject": [
{
"alertid": "1",
"alerttext": "This is test",
"alertdate": "2010-02-11 09:03:40"
},
{
"alertid": "2",
"alerttext": "Another alert",
"alertdate": "2010-02-11 09:11:04"
}
]
}
How can I get my json string to look like the first string when I am constrained to the signature of the put method?
If you're using the net.sf.json library, make yourself a JSONArray and put JSONObjects in it instead.
JSONArray array = new JSONArray();
JSONObject obj = new JSONObject();
obj.put("alertid","1");
array.add(obj);
What you need is a JSONArray that you can then fill with JSONObject's
Try something like this:
JSONArray arr = new JSONArray();
for (JSONObject item : collection)
{
arr.put(item);
}
Or, if you already have a Collection of JSONObject's, you can simply write:
JSONArray arr = new JSONArray(yourFancyCollection);
Then, arr.toString() will look like you asked.

Categories