Java Deserialization when JSON attribute data varies wildly - java

Task at hand: Consider the following model for a JSON response, every API response will conform to this response, obviously the data will vary. Lets call it ResponseModel:
{
"isErroneous": false,
"Message": "",
"Result": null,
"Data": {
"objId": 38,
"objName": "StackO",
"objDescription": "StackODesc",
"objOtherId": 0,
"objLocationId": 1
}
}
How can I deserialize this response regardless of the data in Data: ? Data could contain a single object of different types, e.g a Dog, a Car. It could also contain a collection of Cars or Dogs e.g not just one like above.
It could also contain A car, the cars engine obj, the cars driver seat obj.
In short, the same response is always going to be present but the value of Data can vary wildly, I want to try best to deserialize this to some sort of Result.class for ALL possible scenarios, how do I best approach this? Setting up the class ResponseModel.class is easy for everything except the "Data" type.
Thanks
Here is another example of something which could be returned
{
"isErroneous": false,
"Message": "",
"Result": null,
"Data": [
{
"carId": 1,
"carName": "car#1",
"carDescription": "car#1",
"carOtherId": 1,
},
{
"carId": 2,
"carName": "car#2",
"carDescription": "car#2",
"carOtherId": 2,
},
{
"carId": 3,
"carName": "car#3",
"carDescription": "car#3",
"carOtherId": 3,
},
As you can see in the second example, we are returning a list of cars but in the first response we are just returning a single object. Am i trying to abstract this too much? should I setup custom response(s) for each call of the API etc?
I need to be writing integration tests asserting that the deserialized object is equal to one that I expect everytime.

you can try to check if your json input contains "Data": { or "Data": [ then parse it to seperate class accordingly
But... maybe it's not the best way to do it

Related

GraphQL Query taking in multiple lists as arguments

This is about adding GraphQL to an existing Java api which takes in multiple lists as input.
Background:
I have an existing Java based REST API getFooInformationByRecognizer which takes in a list of recognizers, where each recognizer object contains an id and it's type and returns information corresponding to each id.
The only 3 types possible are A, B or C. The input can be any combination of these types.
Eg:
[{"id": "1", "type": "A" }, {"id": "2", "type": "B"},{"id": "3", "type": "C"}, {"id": "4", "type": "A"}, {"id":"5", "type": "B"}]
Here's it's Java representation:
class FooRecognizer{
String id;
String FooType;
}
This api does a bit of processing.
First extracts out all the input that has ids of type A and fetches information corresponding to those ids.
Similarly, extract out the ids that has type B and fetches information corresponding to those ids and similarly for C.
So, it fetches data from 3 different sources and finally collates them to a single map and returns.
Eg:
ids of type A --> A SERVICE -> <DATA SOURCE FOR A>
ids of type B --> B SERVICE --> <DATA SOURCE FOR B>
ids of type C --> C SERVICE --> <DATA SOURCE FOR C>
Finally does this:
A information + B information + C information and puts this in a Java Hashmap.
The Java representation of the request to this service is:
class FooRequest{
private Bar bar;
List<FooRecognizer> list;
}
The Java representation of the response object from the service is:
class FooInformationResponse{
private Map<String, FooRecognizer> fooInformationCollated;
}
Sample JSON output of the response is:
"output":{
"fooInformationCollated":{
"1":{
"someProperty": "somePropertyValue"
"listOfNestedProperties": [{"x": "xValue", "y": "yValue", "z","zValue"]
"nestedProperty":{
"anotherProperty":{
"furtherNestedProperty": "value"
}
}
}
"2":{
"someProperty": "somePropertyValue"
"listOfNestedProperties": [{"a": "aValue", "b": "bValue", "c","cValue"]
"nestedProperty":{
"anotherProperty":{
"furtherNestedProperty": "value"
}
}
}
}... and so on for other ids in the input
Now, I want to convert this service to GraphQL and here is my query.
query{
getFooInformationByRecognizer(filterBy:{
fooRecognizer: [{
id: "1",
fooType: A
}],
bar: {
barId: "someId",
...<other bar info>
}
}){
fooInformationCollated{
id
fooInformation{
someProperty
listOfNestedProperties
nestedProperty{
anotherProperty{
furtherNestedProperty
}
}
}
}
}
}
Here is my GraphQL schema:
type Query{
getFooInfoByRecognizer (filterBy: getFooByRecognizerTypeFilter!):getFooByRecognizerTypeFilterResponse
}
input getFooByIdentifierTypeFilter{
bar: Bar!
fooIdentifiers: [FooIdentifier!]!
}
input Bar{
barId: String!
....
}
input FooIdentifier{
id: String!
fooIdType: fooIdtype!
}
enum fooIdType{
A
B
C
}
I have a few questions here:
Would this be the best way / best practice to represent this query? Or should I model my query to be able to take in 3 separate lists. Eg: query getFooInformationByRecognizer(barId, listOfAs, listOfBs, listOfCs). Any other choice that I have to query / model?
I found having a complex input type as the easiest. In general, is there any specific reason to choose complex input type over other choices or vice-versa?
Is there any thing related to query performance that I should be concerned with? I've tried looking into DataLoader / BatchLoading but that doesn't quite seem to fit the case. I don't think N+1 problem should be an issue as I will also create separate individual resolvers for A, B and C but the query as can be seen does not make further calls to back-end once JSON is returned in response.
The question is too broad to answer concretely, but here's my best attempt.
While there isn't a definitive answer on 1 complex input argument vs multiple simpler arguments, 1 complex argument is generally more desirable as it's easier for the clients to pass a single variable, and it keeps the GraphQL files smaller. This may be more interesting for mutations, but it is a good heuristic regardless. See the logic explained it more detail e.g. in this article.
The logic explained above echoes your own observations
For this specific scenario you listed, I don't see anything of importance for performance. You seem to fetch the whole list in one go (no N+1), so not much different from what you're doing for your REST endpoint. Now, I can't say how expensive it is to fetch the lower-level fields (e.g. whether you need JOINs or network calls or whatever), but if there's any non-trivial logic, you may want to optimize it by looking ahead into the sub-selection before resolving your top-level fields.

Extracting specific section of JSON from URL in Android?

I am bulding a small app to track Bike Stations around the city, and I have an API that gives me the current status of the availability of bikes in bike stations from the company that provides the service.
My plan is to have a sort of interactive map, with all the markers for each of the bike stations, and when the user taps one of these, they get the information on that specific bike station. I have already all the locations coded in as markers on the map. What I need now is to be able to get the data for the specific bike station the user clicks.
An example of a part of the JSON I get from the API is below:
"number": INT,
"contract_name": "STRING",
"name": "STRING",
"address": "STRING",
"position": {
"lat": DOUBLE,
"lng": DOUBLE
},
"banking": BOOLEAN,
"bonus": BOOLEAN,
"bike_stands": INT,
"available_bike_stands": INT,
"available_bikes": INT,
"status": "STRING",
"last_update": 1588583133000
},
....
This structure is the same for all 100+ nodes of the JSON which I get from the API.
My question is, how would I go about filtering out one individual entry like such from the rest of the JSON. The parameter number is an ID unique to each bike station.
Is there a library that can do this for me? My idea (Very naive) was to save the whole JSON locally each time, and then go through it looking for "number":X and then parse out the data I needed, although this is obviously highly inefficient, I recognize that.
I am only interested in a part of each JSON, to be show to the user: the node's banking, bonus, available_bike_stands, available_bikes and status tags. The status tag is optional, it should simply tell me if the bike station is open (available) or closed.
Thank you very much,
Regards.
Get data from API --> Retrofit
Save local data--> SharePreference, Room
get a part of each JSON --> you create an object that contains some fields you need. when you use retrofit get data from API then it will return the result you desire
class YourClass {
#SerializedName("number")
var number: Int? = null
#SerializedName("banking")
var banking: Boolean? = null
#SerializedName("bonus")
var bonus: Boolean? = null
#SerializedName("available_bike_stands")
var availableBikeStands: Int? = null
//... fields you need
}

how to parse(separate structure and value) json format String in java

let's say I have a String which has a format as Json.
If I want to separate values from the String.
and exchange the values with '#number'.
Currently, I don't know the keys.
Is there any easy way to get this result?
for example,
from
{
"data": [
{
"skills": "Java",
"platforms": "Web"
}
],
"status": "100"
}
to
{
"data": [
{
"skills": #1,
"platforms": #2
}
],
"status": #3
}
with array result [Java, Web, 100]
Probably if you are looking to parse a unknown json and print the values Check this out
I wont be able to give you the exact code you need, but you should be able to implement on similar lines

Checkboxes checked into JSON Format in SpringMVC

I am working on a spring MVC application. I have a sitaution where i need to check some checkboxes from UI and save the checked values in the form of JSON in the backend and i need to convert that into a string.
The picture shows more.
So i want to save like:
[{
Coast : 'East',
States : [ 'NY', 'MI' ]
},{
Coast : 'Central',
States : [ 'TX', 'OK' ]
}].
Please suggest me how can i implement this.
Your question is quite vague so I'm going to assume because you've used the json tag that you're asking for help on how to model this information in JSON and handle it within your Spring app.
You probably want to restructure your JSON schema to support extra fields being set per state. Instead of States being a list of strings, you could change it to a list of objects which has a name and selected field.
I'd also recommend you change the keys in your JSON to be lower case, this enables more fluent mapping between your JSON and model classes.
For example, MI is selected in the below JSON, whereas NY isn't:
[{
"coast": "East",
"states": [{
"name": "NY",
"selected": true
}, {
"name": "MI",
"selected": false
}]
}, {
...same again for West and Central
}]
You could then have some classes along the lines of and use Jackson to map between them:
public class Region {
String coast;
List<State> states;
}
public class State {
String name;
boolean selected;
}

Fullcalendar one feed with multiple JSON objects

Hello Fullcalendar followers, i am trying to make use of threads in my server side to load events to the calendar so i can get a better performance on loading events, meaning:
1 - I only have ONE evenSource feed:
eventSources: [othersources.funcmap] //Employee calendar MAP
2 - In the Servlet ( I'm working on java ):
I am gathering all JSON objets from different sources and joining them together in one large big object (with threads) that i want to send back to Fullcalendar.
2.1 - If i send them individual ( multiple ajax call meaning [othersources.vacations,othersources.faults etc...]) has Strings ( JSON FORMAT ) they work fine and all the feeds are loaded.
This is the JSON object in the "individual" String -> `[{"title":"Vacation day","start":"02-09-2013", etc etc etc}]`
PROBLEM
The problem is when i join them together i make the object like this:
[
[{"title":"Vacation day","start":"02-09-2013", etc etc etc},{"title":"Vacation day","start":"02-09-2013", etc etc etc}],
[{"title":"Fault day","start":"02-09-2013", etc etc etc},{"title":"Faul day","start":"02-09-2013", etc etc etc}],
[{"title":"Birthday fault","start":"02-09-2013", etc etc etc},{"title":"Birthday fault","start":"02-09-2013", etc etc etc}]
]
This is actually a valid JSON object ( without the "etc etc etc" ofcourse :P ) but it doesnt work. fullcalendar wont render the events...
How can i join them together in one big object that Fullcalendar understand?
Or Fullcalendar only knows how to read simple JSON object?
Thank you in advance.
The easiest solution would probably be to flatten the events array before handing it to FullCalendar. But if you insist, then it is also possible by providing a function as a event source in FullCalendar.
The documentation for the function is here: http://arshaw.com/fullcalendar/docs/event_data/events_function/
And this is the basic way to do it:
eventSources: [function (start, end, callback) {
var eventArrays = [
[{
"title": "Vacation day",
"start": new Date()
}, {
"title": "Vacation day",
"start": new Date()
}],
[{
"title": "Fault day",
"start": new Date()
}, {
"title": "Faul day",
"start": new Date()
}],
[{
"title": "Birthday fault",
"start": new Date()
}, {
"title": "Birthday fault",
"start": new Date()
}]
];
// Using underscore.js to flatten the array
var events = _.flatten(eventArrays);
callback(events);
}]
You can check out a working example here: http://jsfiddle.net/kvakulo/q5HET/1/
In the end this makes no sense at all. Multiple AJAX calls are faster, than trying to make one that returns all even with threads in the servlet.
But it worked with the Flat JSON i just joined them all together [{},{}...] with no subarrays.

Categories

Resources