Parse a structured flattened json object to list of object - java

I am current have a Json like :
{
"data":{
"gatewayId":"asd",
"records":[
{
"ms":123,
"points":[
{
"sensorId":"asdasd",
"sensorType":"asdasd",
"batt" : 12,
"kw" : 2
},
{
"sensorId":"123",
"sensorType":"as123dasd",
"batt" : 12,
"kw" : 2
}
]
},
{
"ms":123123,
"points":[
{
"sensorId":"asdasd",
"sensorType":"asdasd",
"batt" : 12,
"kw" : 2
},
{
"sensorId":"123",
"sensorType":"as123dasd",
"batt" : 12,
"kw" : 2
}
]
}
]
},
"gatewayType":"Asdasd"
}
My purpose is to denormalise the object to the lowest level in Java
where the pojo is
class SimpleData {
private String gatewayId;
private String gatewayType;
private Long ms;
private String sensorType;
private Double batt;
private Long kw;
}
For what I did for now, I flatten the json to a list for string as below.
root.gatewayType="Asdasd"
root.data.gatewayId="asd"
root.data.records[0].ms=123
root.data.records[0].points[0].sensorId="asdasd"
root.data.records[0].points[0].sensorType="asdasd"
root.data.records[0].points[0].batt=12
root.data.records[0].points[0].kw=2
root.data.records[0].points[1].sensorId="123"
root.data.records[0].points[1].sensorType="as123dasd"
root.data.records[0].points[1].batt=12
root.data.records[0].points[1].kw=2
root.data.records[1].ms=123123
root.data.records[1].points[0].sensorId="asdasd"
root.data.records[1].points[0].sensorType="asdasd"
root.data.records[1].points[0].batt=12
root.data.records[1].points[0].kw=2
root.data.records[1].points[1].sensorId="123"
root.data.records[1].points[1].sensorType="as123dasd"
root.data.records[1].points[1].batt=12
root.data.records[1].points[1].kw=2
I am thinking is it any logic or library can parse the above list for string to list of SimpleData object?
Sorry, My question maybe not clear, I find a more simple way to solve the problem.
But I need a library to denormalize the json.
for example if the json is :
{
"a" : "1",
"b" : ["2", "3"]
}
will become
[
{
"a" : "1",
"b" : "2"
},
{
"a" : "1",
"b" : "3"
}
]

I believe the Gson library is what you are looking for. It provides simple methods to convert Json array to simple Java objects, and vice versa. Very handy, developed by Google.

I recommend fastjson, which is really fast and quite easy to use. In your case, you only need to define POJO in the structure as your JSON data and parse the JSON to Object. It's created by Alibaba.

Related

Is there a way to extract all values by some key from a list of maps using SpEL?

Let's assume there's a map corresponding to the following structure:
{
"lists": [
{
"list": [
{
"letter": "a"
},
{
"letter": "b"
}
]
},
{
"list": [
{
"letter": "c"
},
{
"letter": "d"
}
]
}
]
}
There's an easy way to get all lists using SpEL (#root['lists']) or all letters of the first list ("#root['lists'][0]['list']") or the first letter of the first list ("#root['lists'][0]['list'][0]"). Also, there's a projection mechanism which allows using construction like "#root['lists'].![#this['list']]" to convert each item of lists to a result of the projection expression.
However, given all these possibilities, I still failed to come up with an expression allowing me to extract all letters from both lists. For the example above, I'd like to get
[
{
"letter": "a"
},
{
"letter": "b"
},
{
"letter": "c"
},
{
"letter": "d"
}
]
I tried to use the projection mechanism to achieve my goal but it didn't really help. The problem I see is that every time SpEL detects a list, it applies the projection expression to each element of the list so any structure of nested lists can't be changed this way.
The problem I solve can be easily solved using JsonPath, however, I assume I could get something wrong and didn't notice a way to achieve the same result using SpEL. I would be happy to listen to any ideas.

How to preserve extra json fields in serialize/deserialization with jackson?

We have a relatively big json document but just need to the special fields of it. So, I defined the needed properties in my model and can serialize/deserialize, well. Recently we are forced to hand over the json document as we received, but since there are so much fields and these fields vary frequently, I'm looking for a method to do this without defining extra fields in the model. I couldn't do it by using an extra Map<String, Object> in the model classes but I guess there should be an solution for it.
Let's suppose my model is like this:
public class Model {
public A a;
}
public class A {
public int i;
}
and the json is like this:
{
"a": {
"i": "1",
"j": {
"q": 2.11,
"e": "94300000",
"r": "book",
"t": null
},
"b": 1
},
"ff": [
{
"gg": "ttttttttt",
"dd": "oooooooo",
"jj": null,
"kk": [
"pppppppp"
]
},
{
"mm": null
}
]
}
How can I do it?

How to compare 2 json by ignoring some attributes and child element orders

I'm seeking for a java library which can give fine grain control on json comparision. (just like XMLUnit)
For example, I have below 2 json document:
Control:
{
"timestamp":1234567,
"items":[
{
"id":111,
"title":"Test Item 111"
},
{
"id":222,
"title":"Test Item 222"
}
]
}
Test:
{
"timestamp":7654321,
"items":[
{
"id":222,
"title":"Test Item 222"
},
{
"id":111,
"title":"Test Item 111"
},
{
"id":333,
"title":"Test Item 333"
}
]
}
I'd like to apply below semantics when comparing them:
Ignore 'timestamp'
When comparing 'items', please do head to head compare against 'id'
Any suggestions?
As point out in your tags you can use Jackson to convert the both json to a Java class.
You can override the equals method within the class with your desired condition.
After all just use equals function in your objects.
JsonUnit seems to help:
https://github.com/lukas-krecan/JsonUnit#options
for my case:
Configuration cfg = Configuration.empty().when(path("items"), then(Option.IGNORING_ARRAY_ORDER, Option.IGNORING_EXTRA_ARRAY_ITEMS)).when(path("timestamp"), thenIgnore());
Diff diff = Diff.create(control, test, "", "", cfg);
assertTrue(diff.similar());

Consume complex api data using retrofit [duplicate]

This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Closed 4 years ago.
{"data":
{
"item1": {
"name" : "Box"
"price" : "50"
},
"item2": {
"name" : "Bottle"
"price" : "250"
}, .....
"item20": {
"name" : "Pen"
"price" : "100"
}
}}
This is my API structure. I cannot create separate POJO classes for 20 items as it is not efficient . What is the best way to fetch the name and price of every item and set them to a recycler view?
You will have to change format of your JSON in order to parse it properly. In addition you forgot to put commas after the "name" value.
Option 1:
{
"data":[
{
"name":"Box",
"price":"50"
},
{
"name":"Bottle",
"price":"250"
},
{
"name":"Pen",
"price":"100"
}
]
}
Option 2:
{
"data":{
"item1":{
"name":"Box",
"price":"50"
},
"item2":{
"name":"Bottle",
"price":"250"
},
"item20":{
"name":"Pen",
"price":"100"
}
}
}
Option 1 is the better choice, since you will be able to represent "data" as an array or a list in android (e.g. ArrayList<Data>).
In general i would suggest you to use a parsing library like GSON
Simple, just use GSON to create an object with SerializableNames to hold the json.
Then simply make an arrayList of your gson compatible object.
The rest is just common adapter interactions.
Example of an API return json object that I use. It must match your json structure.
The example is in Kotlin, but it's the same thing for handling json api response.
Create a simple class then do as mentioned in the image
after clicking the Generate option you see the GsonFromat click then a Box will Prompt , If you are unable to see the GsonFormat then download the GsonFormat plugin. This is the simplest way by which you can easily create Pojo class.
put this into the box and click ok it will automatically create the class for you and you can fetch the data.
{
"data":[
{
"name":"Box",
"price":"50"
},
{
"name":"Bottle",
"price":"250"
},
{
"name":"Pen",
"price":"100"
}
]
}

JSONPath, How to write (create) nested element (Java)

I want to create a json file. I know json simple, but the JsonObject and JsonArray aren't fast enough for me. I want the same efficiency as yaml (for finding and writing values with path).
I want to write this example :
{
"test": {
"test1": 564,
"test2": "der",
"list": [
"tes4",
"test5"
]
},
"exList": [
"tes4",
"test5"
]
}
The question is how to write the json part with JsonPath ?
DocumentContext#add doesn't seems to work
DocumentContext#put needs strange args
With this sample code, I'm getting this error:
PathNotFoundException: Missing property in path $['test1']
(Sorry, I'm French.)
What do you mean strange arguments? You can do:
String path = "$"
String key = "newValue"
int value = 1
yourJson.put(path, key, value)

Categories

Resources