Is there a library or a simple recursive way to get all the property values (without property names or json specific characters) from a random json?
For example, from this object:
{
"a": "aVal",
"b": {
"b1": "b1Val"
},
"c": [
"cVal",
{
"c1":"c1Val"
},
[["c3Val"]]
]
}
I need the values marked with the Val suffix: aVal, b1Val, cVal, c1Val, c3Val
You can use org.json library.
pass the JSON string in a constructor and work with objects after that. Info
Example:
JSONObject root = new JSONObject("{\"a\": \"aVal\",\"b\": {\"b1\": \"b1Val\"},\"c\": [\"cVal\",{\"c1\":\"c1Val\"},[[\"c3Val\"]]]}");
for (Object objKey : root.names()) {
//do things here..
}
Related
I have a json that looks something like this
{
"a": {
"b": [
{
"c": {
"d": [{ "f": "value" }]
}
},
{
"c": {
"d": [{ "f": "value" }]
}
}
]
}
}
I'm looping the data inside b using the following code, then getting the array at d again in a nested loop
for (JsonNode abNode : rootNode.at("/a/b")) {
for (JsonNode cdNode : abNode.at("/c/d")) {
//cdNode.get("f")
}
}
Inside the for loop how can I get the path of something like node.get("f") so that I would get /a/b/0/c/d/0/f and then /a/b/1/c/d/0/f? Does jackson have something to get this or another library? The only thing I can think of right now is just switching to a for i=0 loop
What you are trying to do is also called as Xpath in technical terms.
It is used for html, xml based languages as well as now available in json
You can try jsonpath for this case:
https://www.baeldung.com/guide-to-jayway-jsonpath
https://github.com/json-path/JsonPath
Google's popular GSON library has a method, namely getPath, maybe useful for your purpose:
String json = "...";
JsonReader reader = new JsonReader(new StringReader(json));
System.out.println(reader.getPath());
When reading facebook graph api insights response it can have two types of response
"data":{
"name": "page_posts_impressions",
"values": [
{
"value": 10,//integer value
"end_time": "2019-07-29T07:00:00+0000"
}
]
}
here inside values, value has integer value but in another case
"data":{
"name": "page_posts_impressions",
"values": [
{
"value": { "post":10,
"tab":1
}//json object value
"end_time": "2019-07-29T07:00:00+0000"
}
]
}
here value has json object value, how can I parse these king of json object ?
I believe you are going to parse this JSON to java POJO. Since values is Array of Objects i will suggest to parse that into JsonNode, which is
List<JsonNode> values;
Advantage's in this approach is JsonNode has couple of method to find whether it is Integer or JsonObject
isInt()
public boolean isInt()
isObject
public final boolean isObject()
I have a nested json where in the innermost array there are some keys for which the values could either be a string array or an array of array of strings. The json format is not consistent. How do I parse such a json using gson.
I have tried to write a custom de-serializer (see Gson - parsing json with field that is array or string) but that is throwing exception even before I could detect the attribute as string or array and then update the attribute accordingly.
my json is like this
{
"hits" : {
"total" : 100,
"max_score" : 1,
"hits": [
{"_index": "s1",
"_source":{
"activeOrExpired":[
["active"]
]
}
},
{"_index": "s1",
"_source":{
"activeOrExpired":[
"expired"
]
}
}
]
}
}
My java classes are
public class OuterJson {
#SerliazedName("hits")
public Hits hitsOuter;
public static class Hits {
public List<InnerHits> innerHits;
}
}
public InnerHits {
public String _index;
public Source _source;
public static class Source {
public List<List<String>> activeOrExpired;//I declare this field as
//list of list of strings
public Source() {
activeOrExpired = new ArrayList<>();
}
}
}
public class CustomDeserializer implements JsonDeserializer<OuterJson> {
#Override
public OuterJson deserialize(JsonElement elem, Type type, JsonDeserializationContext context) throws JsonParseException {
JsonObject outerObj = elem.getAsJsonObject();
JsonElement innerHits = outerObj.get("hits").getAsJsonObject().get("hits");
//I want to then detect the type of "activeOrExpired" and convert it
//to list of list of strings if it is present just as a string
//I am getting exception in the below line
InnerHits[] innerHitsArray = new Gson().fromJson(innerHits, InnerHits[].class);
//omitting below code for brevity since my code is failing above itself.
}
}
The exception is
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was String at path $[0]._source.activeOrExpired[0]
Here the innermost "hits" array has the "_source" array which has a field "activeOrExpired" this field is coming either as an array of Strings or array of array of strings.
How should I design the custom deserializer to handle such case?
I am new to gson and was following the method mentioned in the above link. My code is described above, could anyone please give me some hint on progressing. Thanks!
You can use DSM stream parsing library for such a complex JSON or XML. By using DSM you don't need to create java stub file to deserialize. you can directly deserialize to your own class.
It uses YAML based mapping file.
Here is the solution to your question. I am not sure about your object structure. I only deserialize some part of it.
Mapping File:
result:
type: object # result is map.
path: /hits
fields:
hits:
path: hits
type: array
fields:
index:
path: _index
source:
path: _source/activeOrExpired
filter: $value!=null
type: array # source is also array.
Use DSM to filter JSON and deserialize.
// you can pass your class to deserialize directly to your class instead of getting map or list as a result.
//DSM dsm=new DSMBuilder(new File("path/to/maping.yaml")).create(YourClass.class);
DSM dsm=new DSMBuilder(new File("path/to/maping.yaml")).create();
Map<String,Object> hits= (Map<String,Object>)dsm.toObject(new File("path/to/data.json");
json representation of hits variable
{
"innerHits" : [ {
"index" : "s1",
"source" : [ "active" ]
}, {
"index" : "s1",
"source" : [ "expired" ]
} ]
}
I am trying to define java generic type in method and I am not able to do so. I went through lot of posts but haven't figured it out.
I have a JSON which will be converted to java LinkedHashMap by Mule Dataweave. Here is simple JSON
{
"a": {
"b": {
"c": [{
"name": "abc"
},
{
"name": "xyz"
}
],
"d": "e"
},
"f": "g"
}
}
Now I want to use that JSON converted to LinkedHashMap in java method.
I tried something like
public void test(LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap>> payload)
but the value can be recursive LinkedHashMap until I get key and value as String. I don't know how deep it can go as it is based on JSON response. How can I define it in java generics?
As Java Does not support Union Types you can not model this other than
public void test(LinkedHashMap<String, Object> payload)
Where you know that an Object is Either a Map<> or String or List.
I am trying to parse a JSON .txt file into a JAVA object using GSON. The JSON file has the following structure:
{
"event0" : {
"a" : "abc",
"b" : "def"
},
"event1" : {
"a" : "ghi",
"b" : "jkl",
"c" : "mno"
}
}
I have read the text file into a String called dataStr. I want to use the fromJson method to capture the events into the following JAVA class:
public class Event {
private String a;
private String b;
private String c;
public Event() {}
}
The problem is that the JSON might have one extra field "c" in some of the elements. I want to parse all the events into Event class objects, and for the cases where there is no "c" field, I want to make it null or zero in my object. It is not known beforehand which of the elements will have the "c" field.
Specifically, I was not able to figure out how to handle one extra field in some of the JSON elements. I want to do something along the lines of:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
But I am stuck with first, how to iterate over the events in the Json file, and secondly, how to handle some occasional missing fields into the same Event object. I would really appreciate a kick in the right direction. Thank you all.
I am fairly new to JSON parsing, and might have missed something in the following answers:
Using Gson to convert Json into Java Object
Mapping JSON into POJO using Gson
Using gson to parse json to java object
Parse JSON into a java object
How to parse a json file into a java POJO class using GSON
I'm not sure if I understood your question right. As per my understanding, you are trying to convert a json object with an extra field which is not available in the java class. Frankly, I don't understand why you want that or if it's possible to start with. You can have a workaround by converting the json to Map.
Map map = gson.fromJson(jsonString, Map.class);
Gson automatically do that for you.
So, if you have a class "Alpha" with 3 fields ("a", "b" and "c") and you try to work on a json object that has 2 fields with names that match with Alpha's "a" and "b", Gson will fill "a" and "b" with json file's value and "c" will automatically set as null.
So, in your case, if you write this:
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
And in your json there are events with only 2 fields (that match with any Event's class fields) and events with all fields set, you will get a list of Events with no errors. Maybe you'll get some fields null, but the code will work.
I hope to be helpful! Ask for further informations, if you want to!
EDIT
Note that your json file has not to be .txt but .json instead!
First I believe your JSON should look like this:
{
"events": [
{
"name": "event0",
"a": "abc",
"b": "def"
},
{
"name": "event1",
"a": "abc",
"b": "def",
"c": "mno"
}
]
}
This will need two classes for your model:
public List<Event> events = null;
public class Event {
public String name;
public String a;
public String b;
public String c;
}
And then then with GSON
Events events = gson.fromJson(jsonData, Events.class);
Also I recommend to always use an online validator for JSON so you are sure your JSON structure is correct before coding against it.
https://jsonlint.com/
Or for formate the JSON:
http://jsonprettyprint.com/
Also this website can create the Java classes for you from either a JSON Schema or by using an example file.
http://www.jsonschema2pojo.org/
Try the below code snippet:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());
In the source code of Gson has a very clear explain