Get keys from multiple JSON objects - java

I have a JSON object that contains undetermined pattern and I need to get all keys of the json object and the sub-objects.
Here's an example of a JSON file:
{
"users": {
"address": [
{
"rue": "ruetest",
"postal": 1111
},
{
"rue": "ruetest",
"postal": 2222
}
],
"type": "string",
"user": [
{
"argent": 122,
"id": 1,
"nom": "user1",
"prenom": "last1"
},
{
"argent": 200,
"id": 2,
"nom": "user2",
"prenom": "last2"
},
{
"argent": 1205,
"id": 3,
"nom": "user3",
"prenom": "last3"
}
]
}
}
and I need to have output like this:
[users,type,address,user,argent,id,nom,prenom] or something like this

I don't think there's really a built-in way to do this, but you could achieve your goal by making a function that does it. Something like (in pseudocode):
public Set getJsonKeys(JSON json) {
Set s = new Set();
for (Entry e : json.entrySet()) {
s.add(e.key);
if (e.value instanceof JSON) s.addAll(getJsonKeys(e.value));
}
return s;
}
I chose a Set rather than List to prevent duplicate entries. If you want to include keys of lists just add a check if e.value is a list and if so, iterate over elements and add getJsonKeys(element) for all elements.

Have you tried the Genson Java Collections mode?
It would give you easy generic access to arbitrary JSON files in java.

If you use the fastjson framework, I think you can use the following code to get all the keys:
JSONObject jsonObject = new JSONObject(jsonData);
Iterator keys = jsonObject.keys();
while (keys.hasNext()){
String key = String.valueOf(keys.next());
}

Related

How to filter particular key from Map<String,Object> when key is flatjson

I am getting a response mentioned below.I want to filter keys having state only how can we do this thing
Example
{
"response[0].id": 14,
"response[0].x": "ABCDED",
"response[0].y.code": "RERWRR",
"response[0].z.value": "TTTRRWW",
"response[1].id": 13,
"response[1].x": "RERERE",
"response[1].y.code": "TRTYUUU",
"response[1].z.value": "QWEAWE",
"response[2].id": 3,
"response[2].x": "POPOPO",
"response[2].y.code": "YUYUYU",
"response[2].z.value": "RUSUSUS",
"totalRecords": 3,
"limit": 100,
"offset": 0
}`
I only want to filter only response[0].x ,response[1].x ,response[2].x from Map
as #Flown already mentioned, the structure of your json doesn't really look nice. Something like this would make more sense:
{
"responses": [
{
"id": 3,
"x": "ABC",
"y": {
"code": "CODE"
},
"z": {
"value": "VALUE"
}
}, {
...
}
],
...
}
Or even better if you could get rid of x, y and z and have something like that:
{
"responses": [
{
"id": 3,
"status": "STATUS",
"code": "CODE"
"value": "VALUE"
}, {
...
}
]
}
If you can't change the structure for whatever reason you could filter the map like that:
Map<String, Object> filteredMap = map.entrySet().stream()
.filter(entry -> entry.getKey().contains("].x")
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
This returns you a Map only with entries where the key contains the string ]x. which should be fine in your example (response[1 ].x , response[2 ].x , ...).
This should work but is still not really a nice solution. It would be better if you could change the json structure.

Remove a String from Json Object

I am trying to convert an Avro Kafka Event to Json and need to manipulate The Avro Event by Removing Strings from this Event.
I am using GSON Library to manipulate the Json String Object but somehow its not removing the intended String.
JsonElement je = new Gson().fromJson(matchRequest, JsonElement.class);
JsonObject jo = je.getAsJsonObject();
jo.remove("com.XXX.XXXX");
jo.remove("com.XXX.XXX");
jo.remove("com.XXX.XXX");
System.out.println("#################"+jo);
Json String I am Receiving as matchRequest is
{"interaction_id":"321","customer_id":"32","context_id":"123","work_id":"ewq","work_request_id":"213","task_type":"123","match_type":"wert","resource_list":{"com.xxx.xxxx":{"rank":1,"resource_data":{"com.xxx.xxxx":{"account_id":1,"source_name":"Mankind","channel_id":"voice"}}}},"service_list":{"com.xxx.xxxx":{"rank":5,"priority":1,"resource_count":"gvk","min_proficiency":"10","max_proficiency":"1","attributes":{"com.xxx.xxxx":{"category":"edw","value":"33232"}},"resource_offered":{"com.xxx.xxxx":{"agent_id":"rewq","account_id":"123","source_name":"wqe","resource_address":"ewq","source_address":"rewq","channel_id":"212","channel_provider":"wqe"}}}},"matching_state":"OFFERED"}
JSON Format
"interaction_id": "321",
"customer_id": "32",
"context_id": "123",
"work_id": "ewq",
"work_request_id": "213",
"task_type": "123",
"match_type": "wert",
"resource_list": {
"com.XXXXXX": {
"rank": 1,
"resource_data": {
"com.XXXX": {
"account_id": 1,
"source_name": "Mankind",
"channel_id": "voice"
}
}
}
},
"service_list": {
"com.XXXX": {
"rank": 5,
"priority": 1,
"resource_count": "gvk",
"min_proficiency": "10",
"max_proficiency": "1",
"attributes": {
"com.XXXX": {
"category": "edw",
"value": "33232"
}
},
"resource_offered": {
"com.XXXX": {
"agent_id": "rewq",
"account_id": "123",
"source_name": "wqe",
"resource_address": "ewq",
"source_address": "rewq",
"channel_id": "212",
"channel_provider": "wqe"
}
}
}
},
"matching_state": "OFFERED"
}
When you look at the documentation of the remove() method, it needs a key from the JSON object in parameter.
However, the JSON you are receiving does not contain "com.xxx.xxxx" as key, but some keys, like "resource_list", are linked to another JSON object containing "com.xxx.xxxx" as a key.
You may want to look recursively into the JSON object you receive to remove the intended String.
You need to perform your operation over your array:
jo.getAsJsonObject("resource_list").remove("com.XXX.XXXX");
This should do the trick.

Create POJO from json generated by key=>value Array

I want create a pojo from a json like this
{
"1": [
{
"idmapel": 1,
"label": "Fisika"
},
{
"idmapel": 2,
"label": "Kimia"
},
{
"idmapel": 3,
"label": "Biologi"
},
{
"idmapel": 4,
"label": "Matematika"
},
],
"2":[
{
"idmapel": 1,
"label": "Fisika"
}
]
}
when i generate from http://www.jsonschema2pojo.org/ it created a 1 and 2 class, but imagine if i have more than 2 keys. i want to be able to access element by something like this ObjectClass::getList(1) or ObjectClass::getList(2)
You can use a Map to do this.
Map<String, List<Pojo>> map = deserialize(jsonSring);
where Pojo is the class which has fields idmapel and label, deserialize is a method which deserializes the json to object and jsonString is the json string value to deserialize. Then you can access lists with keys
List<Pojo> list1 = map.get("1");
List<Pojo> list2 = map.get("2");

The sum of several items in a json

I have a JSON source with more empty_slots elements (in the example exist below only one, but in the reality exist more stations with empty_slots). How can I sum the values from empty_slots and return as double? Thanks!
JAVA
public static double getValueFromJSONString(String jString) throws JSONException
{
JSONObject json = new JSONObject(jString);
return json.getJSONObject("empty_bikes").getDouble(jString);
}
JSON
{"network": {
"company": [
"Gewista Werbegesellschaft m.b.H"
],
"id": "citybike-wien",
"location": {
"city": "Wien",
},
"stations": [
{
"empty_slots": 3,
"extra": {
"slots": "26",
},
"free_bikes": 23
}]}
Checkout JsonPath. Below code is not tested but should work with RestAssured dependency - https://github.com/rest-assured/rest-assured
JsonPath jsonPath = new JsonPath(jsonString);
List<Integer> companyEntityIds = jsonPath.getList("network.stations.empty_slots");
Once you have the array you can just use a stream or whatever to add these up.

java - Jackson Json traverse encapsulated tree

I have a schema like this (simplified):
{
"range": {
"offset": 0,
"limit": 1,
"total": 2
},
"items": [
{
"id": 11,
"name": "foo",
"children": [
{
"id": 112,
"name": "bar",
"children": [
{
"id": 113,
"name": "foobar",
"type": "file"
}
],
"type": "folder"
},
{
"id": 212,
"name": "foofoo",
"type": "file"
}
],
"type": "room"
},
{
"id": 21,
"name": "barbar",
"type": "room"
}
]
}
I need to read only specific values like "id" from the first room (item). For this I need to iterate trough all items on every level (n items for root, n items for n children) with type folder or file.
For now i have this code:
POJO
public static class Item {
public int id;
}
Jackson Tree Iteration
ObjectMapper mapper = new ObjectMapper();
com.fasterxml.jackson.databind.JsonNode root = mapper.readTree(JSON);
root = root.get("items").get(0);
TypeReference<List<Item>> typeRef = new TypeReference<List<Item>>(){};
List<Item> list = mapper.readValue(root.traverse(), typeRef);
for (Item f : list) {
System.out.println(f.id);
}
How can i get all id's of all children in all items with specific type?
How to avoid the "Unrecognized field" exception without defining the whole schema?
Thank you very much for your help!
Try using java8 functions it has lot to do it in lesser lines ,
ObjectMapper mapper = new ObjectMapper();
Pass your json value
Map obj = mapper.readValue(s, Map.class);
List<Object> items= (List<Object>) obj.get("items");
Object[] Ids= items
.stream()
.filter(items-> ((Map)items).get("type").equals("room"))
.toArray()
Use the readTree(...) method to parse the JSON without needing to define the entire schema and find Nodes called "id".
You can then use findValues("id") to get the List of values back.

Categories

Resources