Parsing a JSON array WITHOUT a wrapper class - java

I'm trying to parse a JSON array into a Java ArrayList using Gson.
{
"fathers": [
{
"name": "Donald",
"age": 47,
"children": [
{
"name": "Johnny",
"age": 6
},
{
"name": "Donna",
"age": 15
},
{
"name": "Alan",
"age": 21
}
]
},
{
"name": "George",
"age": 35,
"children": [
{
"name": "Cynthia",
"age": 10
},
{
"name": "Stacey",
"age": 5
},
{
"name": "Dewey",
"age": 2
}
]
}
]
}
I'm trying to parse the "fathers" array into an ArrayList... However, I can't do it directly, since the fathers array is wrapped by a JSON object. Normally, I would do something like this:
Type fathersListType = new TypeToken<ArrayList<Father>>(){}.getType();
fathersArrayList = gson.fromJson(fathersJson, fathersListType);
But, since the fathers array is wrapped by an object, I get this error:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
Is there a way to parse said array, without having to declare a wrapper class, that contains a "fathers" array? Like ignoring the wrapping object, or extracting the JSON array from it.

You can parse the root object as a Map:
Type rootType = new TypeToken<Map<String, List<Person>>>(){}.getType();
Map<String, List<Person>> root = gson.fromJson(fathersJson, rootType);
List<Person> fathersList = root.get("fathers");

Something like this should work:
String data = "{...}"; // Your JSON
JsonArray array = new JsonParser().parse(data).getAsJsonObject().get("fathers").getAsJsonArray();
List<Father> fathers = Arrays.asList(new Gson().fromJson(array, Father[].class));
Arrays.asList comes from https://commons.apache.org/

Related

How would I access this key within a JSON object in Java?

I've been having some problems iterating through a JSON object in Java.
Specifically, I'd like to save each value for "name" to the string array "nameList". I've looked up how to do this, and I haven't found a way for this situation.
String[] nameList = new String[]{};
{
"data": {
"Narray": {
"0":
{
"_id": "001",
"name": "studio",
"date": "02141992"
},
"1":
{
"_id": "002",
"name": "venue",
"date": "09041999"
}
}
}
Ideally you'd want Narray to be an actual JSON array, enclosed in [], with each element being another object, containing the property you need, like this:
{
"Narray": [
{
"_id": "001",
"name": "studio",
"date": "02141992"
},
{
"_id": "002",
"name": "venue",
"date": "09041999"
}
]
}
Then you can use jackson to decode the JSON string into a POJO structure. Once you have the objects, you can iterate over the array and retrieve the property you need into a list.
I assume that you only want to save each value of name into a String[] (string array), so you don't need to deserialize the JSON string to POJO, just use basic API to achieve what you want as follows:
BTW, your JSON string is invalid, you miss a right bracket.
ObjectMapper mapper = new ObjectMapper();
JsonNode nArray = mapper.readTree(jsonStr).get("data").get("Narray");
String[] nameList = new String[nArray.size()];
for (int i = 0; i < nArray.size(); i++) {
nameList[i] = nArray.get(String.valueOf(i)).get("name").asText();
}
System.out.println(Arrays.toString(nameList));
Console output:
[studio, venue]

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.

Create a JSON without a key

We wanted to create a JSON structure as below in Java
{
[
{
"key": "ABC001",
"value": true
},
{
"key": "ABD12",
"value": false
},
{
"key": "ABC002",
"value": true
},
]
}
To implement this we created a class and had a list private property inside it.
But that is creating a key values
class Response{
private List<Property> values;
// setter getter for this private property
}
The output for this is
{
values : [
{
"key": "ABC001",
"value": true
},
......
]
Is there a way we create the array without the key and inside the { }?
Unfortunately, what you're trying to build is not a valid json.
You can try to validate it here.
With this "json", for example, it would be impossible to read the array, because it has no key.
{
"foo_key" : "bar",
[
{
"key": "ABC001",
"value": true
},
{
"key": "ABD12",
"value": false
},
{
"key": "ABC002",
"value": true
},
]
}
Parsing a json like this one, you could get "bar" because it has a key ("foo_key"), but how could you get the array?
The code you're using is already correct for a valid json.
So, for some reason you want an invalid json, which is an array contained between {}s. Here's how you can do it (I'll assume you use google-gson to make and parse jsons, since you didn't include your code):
// example of the creation of the list
List<Property> values = new ArrayList<>();
values.add(new Property("ABC001", true));
values.add(new Property("ABD12", false));
values.add(new Property("ABC002", true));
//
Gson gson = new Gson();
String json = gson.toJson(values, new TypeToken<List<Property>>() {}.getType());
json = "{" + json + "}";// gotta do what you gotta do...

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