Parse nested JSON with varying number of entries - java

I'm working on a bus transit app and one of the network calls I need to make gets the trip info on how to get from point A to point B. The bus transit API has a method that provides this info. The method returns up to 3 viable itineraries, and each itinerary has a variable amount of legs. There are also two types of legs, walking legs and riding legs.
I was wondering on how I should go about parsing this data and then transferring it to the UI. What's throwing me off is that the nested entries also have nested arrays of variable length (that can be of either two types). To first retrieve the data I think using an ArrayList of ArrayList could work. Should I then create two models that correspond to the two type of legs, add the data to those, and then dynamically add those to the listView I'm going to use to display the results? (I would also have to dynamically add the itineraries).
Oh and another thing. If the bus you need to get on finishes a route and starts a new one (while you need to stay on it the whole time) It will return multiple services in a single leg and I have no idea how to efficiently check for that and convey that to the user.
This is what I have so far (only have code for parsing right now).
final String JSON_ITINERARIES = "itenararies";
final String JSON_STOP_NAME = "stop_name";
final String JSON_STOP_LAT = "stop_lat";
final String JSON_STOP_LONG = "stop_long";
final String JSON_STOP_ID = "stop_id";
try {
JSONArray itinerariesArray;
JSONObject stopsJson = new JSONObject(JsonStr);
itinerariesArray = stopsJson.getJSONArray(JSON_ITINERARIES);
ArrayList itinerariesArrayList = new ArrayList<ArrayList<String>>(itinerariesArray.length());
for (int i = 0; i < itinerariesArray.length(); i++) {
JSONObject singleTrip = itinerariesArray.getJSONObject(i);
JSONArray singleTripLegsJSON = singleTrip.getJSONArray("legs");
ArrayList legsArrayList = new ArrayList<String>(singleTripLegsJSON.length());
for (int j=0; j<singleTripLegsJSON.length(); j++) {
JSONObject SingleTripObjectSingleLeg = singleTripLegsJSON.getJSONObject(j);
String TYPE = SingleTripObjectSingleLeg.getString("type")
//?????
}

I recommand you to use GSON. GSON is very very very useful tool for JSON.
First, use http://www.jsonschema2pojo.org/ to make class from json.
Copy & paste your json string to this site,
select "source type : JSON",
select "Annotation style: GSON",
press "Preview" OR "JAR" to get JAVA classes.
Second, use GSON to parse your json string. Visit Here to get more examples.
example:
private Gson gson = new Gson();
String sampleData = //
"[" //
+ "{\"info\": {\"place\": \"place1\"},"
+ "\"events\": {\"info\": \"555f1fc297f229004dd6e8aa\",\"time\": \"5\",\"image\": \"555f1fc2d197270b6c732d3b\",\"event_name\": \"555f1fc224d1cb629a8ef603\"}},"
+ "{\"info\": {\"place\": \"place3\"},"
+ "\"events\": {\"info\": \"555f1fc283c7b150ede89c05\",\"time\": \"7\",\"image\": \"555f1fc2bf5fa8a3b320e0ca\",\"event_name\": \"555f1fc20d40f1b478610505\"}},"
+ "{\"info\": {\"place\": \"place2\"},"
+ "\"events\": {\"info\": \"555f1fc29163e85ae42e7518\",\"time\": \"6\",\"image\": \"555f1fc21506a186c2d34a92\",\"event_name\": \"555f1fc272a06e68b8c3f4b7\"}}" + " ]";
java.lang.reflect.Type listType = new TypeToken<List<Event>>() {
}.getType();
ArrayList<Event> eventList = gson.fromJson(sampleData, listType);

Related

How can i add additional field to each object in array node using jackson java?

i have list of masters that have two fields that are name and rating and after serialization to array node i need to add one more field to each object
for example i have json
[{"masterName":"Bruce","rating":30},{"masterName":"Tom","rating":25}]
and i have list of servisec in json format that look like that
[{"masterName":"Bruce","services":["hair coloring","massage"]},{"masterName":"Tom","services":["hair coloring","haircut"]}]
i need it to looks something like that
[{"masterName":"Bruce","rating":30,"services":"hair coloring,massage"},{"masterName":"Tom","rating":25,"services":"hair coloring, haircut"}]
How can do it by using jackson?
I would approach it this way. Since you want to use Jackson.
First of all, I would extend the Master class by adding the services (which seems to be an array with Strings).
So the class would look something like this:
public class Master
{
private String masterName;
private int rating;
private List<String> services = new ArrayList<>(); // THE NEW PART
// Whatever you have else in your class
}
Then you could get your JSON array, I am supposing that it comes as a String for simplicity. Serialize this array in an array with Master objects and then you can add the services as said above.
e.g.
String yourJsonString = "[{\"masterName\":\"Bruce\",\"rating\":30},{\"masterName\":\"Tom\",\"rating\":25}]";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List<Master> theListOfMasters = new ArrayList<>();
// Read them and put them in an Array
Master[] mastersPlainArr = mapper.readValue(yourJsonString, Master[].class);
theListOfMasters = new ArrayList(Arrays.asList(mastersPlainArr));
// then you can get your masters and edit them..
theListOfMasters.get(0).getServices.add("A NEW SERVICE...");
// And so on...
// Then you can turn them in a JSON array again:
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(theListOfMasters);

Get all objects on ArrayList

can some one explain me how to get all categories value from
"categories":[{"1":1,"2":"orange","3":"mango","4":"guava","5":5,"6":6}]
result my like this 1 = 1, and 2 = orange,
what must i do i am stuck in here
public RealmList<CategoryRealm> categories;
or
p.categories = new RealmList<>();
can some one explain to me what must i do in the next method i am stuck tried searching but so damn hard to learn its diferent.
Use GSON library.
Create an object that matches your structure. I'm assuming you have a structure of
{
"categories"://the rest of the stuff here
}
class MyParentObject{
#SerializeName("categories")
ArrayList<String> myList;
}
Then use GSON to create it
MyParentObject obj = (MyParentObject)getGson().fromJson(json, classType);
and your done.
If the base is just the categories string then your json is badly formatted and you may have to do a subString call to get starting index of "[" and go from there into json management.

Iterate JSON and get fields from JSON

I've tried different solutions but I'm not able to iterate through this JSON and/or get direct specific values.
Could any one help on:
Iterating through all the fields sequentially.
Getting direct access to some fields (eg. when getting this response, access directly to "packet-count" where its value equals 3281).
{"flow-node-inventory:flow":[{"id":"42","priority":10,"table_id":0,"opendaylight-flow-statistics:flow-statistics":{"packet-count":3281,"byte-count":317738,"duration":{"nanosecond":252000000,"second":3432}},"idle-timeout":10000,"cookie":31,"instructions":{"instruction":[{"order":0,"apply-actions":{"action":[{"order":0,"output-action":{"output-node-connector":"1","max-length":0}}]}}]},"match":{"ethernet-match":{"ethernet-source":{"address":"00:00:00:00:00:02"},"ethernet-destination":{"address":"00:00:00:00:00:01"}}},"hard-timeout":50000,"flags":""}]}
I tried to use org.json but any other library would be okay.
You will have to check the structure of your JSON Object and create a structure for the entities you encounter accordingly. For instance, the first thing in your JSON object is an array, so this is the first thing you should care about. Imagine it as a continuous encapsulation. Check the code below for more information.
JSONObject jobj = new JSONObject(stringJson);
JSONArray flowNodeInv = jobj.getJSONArray("flow-node-inventory:flow");
for (int i = 0; i < flowNodeInv.length(); i++){
JSONObject segment = (JSONObject) flowNodeInv.get(i);
JSONObject stats = segment.getJSONObject("opendaylight-flow-statistics:flow-statistics");
int number = stats.getInt("packet-count");
System.out.println("packet-count: "+ number);}
Try This
jObject = new JSONObject(contents.trim());
Iterator<?> keys = jObject.keys();
while( keys.hasNext() ) {
String key = (String)keys.next();
if ( jObject.get(key) instanceof JSONObject ) {
}
}
To get direct access to the fields you can create a Java Object from the JSON String using an ObjectMappet (com.fasterxml.jackson). For example:
ObjectMapper mapper = new ObjectMapper();
MyClass myClass = mapper.readValue(jsonString, MyClass.class);

Logical solution for creating a JSON structure

I am not sure if it possible or not but I think it can be done using JSONArray.put method.
Heres my problem:
I have got two lists:
ArrayList<Students> nativeStudents;
ArrayList<transferStudents> transferStudents = nativeStudents.getTransferStudentsList();
The JSON that I generate with transferStudents list is right here: http://jsfiddle.net/QLh77/2/ using the following code:
public static JSONObject getMyJSONObject( List<?> list )
{
JSONObject json = new JSONObject();
JsonConfig config = new JsonConfig();
config.addIgnoreFieldAnnotation( MyAppJsonIgnore.class );
if( list.size() > 0 )
{
JSONArray array = JSONArray.fromObject( list, config );
json.put( "students", array );
}
else
{
//Empty Array
JSONArray array = new JSONArray();
json.put( "students",
array );
}
return json;
}
Now what I want to get is JSON data with following structure: http://jsfiddle.net/bsa3k/1/ (Notice the tempRollNumber field in both array elements).
I was thinking of doing: (The if condition here is used for a business logic)
if(transferStudents.getNewStudentDetails().getRollNumber() == nativeStudents.getNativeStudentDetails.getStudentId()){
json.put("tempRollNumber", transferStudents.getNewStudentDetails().getRollNumber());
}
but this would add tempRollNumber outsite the array elements, I want this JSON element to be part of every entry of students array.
PS: I cant edit the transferStudents class in order to add tempRollNumber field.
Since no one has come up with anything better I'll turn my comments above into an answer.
The best way to handle this is to create an object model of your data and not create the JSON output yourself. Your app server or container can handle that for you.
Though you cannot change the objects you receive in the List you can extend the object's class to add your own fields. Those fields would then appear in the JSON when you marshall it.

JSON parsing to Java - Android application

I need help with parsing json string in Java Android Appl.
Text of JSON file:
{"data":{"columns":["location_id","name","description","latitude","longitude","error","type","type_id","icon_media_id","item_qty","hidden","force_view"],"rows":[[2,"Editor","",43.076014654537,-89.399642451567,25,"Npc",1,0,1,"0","0"],[3,"Dow Recruiter","",43.07550842555,-89.399381822662,25,"Npc",2,0,1,"0","0"] [4,"Protestor","",43.074933,-89.400438,25,"Npc",3,0,1,"0","0"],[5,"State Legislator","",43.074868061524,-89.402136196317,25,"Npc",4,0,1,"0","0"],[6,"Marchers Bascom","",43.075296413877,-89.403374183615,25,"Node",22,0,1,"0","0"] [7,"Mary","",43.074997865584,-89.404967573966,25,"Npc",7,0,1,"0","0"]]},"returnCode":0,"returnCodeDescription":null}
How can get values: location_id, name, latitude, longitude.
Thanks, Michal.
Using manual parsing you can implement it like this:
JSONArray pages = new JSONArray(jsonString);
for (int i = 0; i < pages.length(); ++i) {
JSONObject rec = pages.getJSONObject(i);
JSONObject jsonPage =rec.getJSONObject("page");
String address = jsonPage.getString("url");
String name = jsonPage.getString("name");
String status = jsonPage.getString("status");
}
in your case note that your outer elemnt data is type of JSONObject and then you have a JSONArray
mine json file:
[{"page":{"created_at":"2011-07-04T12:01:00Z","id":1,"name":"Unknown Page","ping_at":"2011-07-04T12:06:00Z","status":"up","updated_at":"2011-07-04T12:01:00Z","url":"http://www.iana.org/domains/example/","user_id":2}},{"page":{"created_at":"2011-07-04T12:01:03Z","id":3,"name":"Down Page","ping_at":"2011-07-04T12:06:03Z","status":"up","updated_at":"2011-07-04T12:01:03Z","url":"http://www.iana.org/domains/example/","user_id":2}}]
note that mine starts from [, which means an array, but yours from { and then you have [ array inside. If you run it with a debugger, you can see exactly what´s inside your json objects.
There are also better approaches like:
Jackson
Jackson-JR (light-weight Jackson)
GSON
All of them can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.
First of all, you need to know about Json parsing in android, so for that first read this: JSONObject, in that class, you will see the below methods:
getJSONArray(String name)
getJSONObject(String name)
getString(String name)
and many more methods to be used while implementing JSON parsing in android.
Update:
And if you are still confused then click on below link to have many examples available on web: Android JSON Parsing
You need to use the GSON lib
http://code.google.com/p/google-gson/
Object Examples
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
==> json is {"value1":1,"value2":"abc"}
Note that you can not serialize objects with circular references since that will result in infinite recursion.
(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
==> obj2 is just like obj
If you mean to navigate easily the Json Tree, you can use JSON Path, that is query system, similar to XPath to XML, that you can use to pick some elements in a json tree using text expressions.
http://code.google.com/p/json-path/ That's a good implementation
If you just mean that you want to parse that JSon you can use Gson from google (that is compatible with Android I guess).
This contains a complete example for your case.

Categories