I am able to write to a JSON file. Why is it that, if I write another object from a different subclass, the JSON file will be rewritten and only display fields for that new subclass....previous entries will be deleted...
Example:
//evt is an ArrayList<Event> list
//evt contains a list of objects of type TimedEvent
//TimedEvent extends Event class
//Event is the abstract class
toJson("C://myJson.json", evt);
The above will generate this:
[
{
"eventStartDateTime": {
"year": 2014,
"month": 3,
"dayOfMonth": 11,
"hourOfDay": 11,
"minute": 5,
"second": 0
},
"eventEndDateTime": {
"year": 2014,
"month": 3,
"dayOfMonth": 11,
"hourOfDay": 12,
"minute": 5,
"second": 0
},
"title": "My First Event",
"eventId": "2u0-zBGhkdX8FcbFCFp3ah",
"completed": false
}
]
But if I change the list to a different object from a different subclass, the previous fields in the first JSON file disappears.
//evt is an ArrayList<Event> list
//evt this time contains a list of objects of type FloatingEvent
//FloatingEvent also extends Event class
toJson("C://myJson.json", evt);
The above will generate this:
[
{
"title": "My First Event",
"eventId": "2u0-zBGhkdX8FcbFCFp3ah",
"completed": false
},
{
"title": "My Second Event",
"eventId": "19Jv07-a4ICaex.8fceZOc",
"completed": false
}
]
How can I make sure that the method toJson appends the new event but keep whatever fields written the first time.
What I need is something like this..isit possible??....how do I separate the two objects then when retrieving?
[
{
"eventStartDateTime": {
"year": 2014,
"month": 3,
"dayOfMonth": 11,
"hourOfDay": 11,
"minute": 5,
"second": 0
},
"eventEndDateTime": {
"year": 2014,
"month": 3,
"dayOfMonth": 11,
"hourOfDay": 12,
"minute": 5,
"second": 0
},
"title": "My First Event",
"eventId": "2u0-zBGhkdX8FcbFCFp3ah",
"completed": false
},
{
"title": "My Second Event",
"eventId": "19Jv07-a4ICaex.8fceZOc",
"completed": false
}
]
The code I used to write the JSON file:
public static String toJson(String fileName, List<Event> evt) {
fileName = Utilities.getDefaultFileName();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = "";
try {
File file = new File(fileName);
// if file does not exists, then create it
if (!file.exists()) {
json = gson.toJson(evt);
file.createNewFile();
FileWriter writer = new FileWriter(fileName);
writer.write(json);
writer.close();
} else {
ArrayList<Event> currentEventList = fromJson(fileName);
for (Event newEvent : evt) {
currentEventList.add(newEvent);
}
json = gson.toJson(currentEventList);
file.delete();
file.createNewFile();
FileWriter writer = new FileWriter(fileName);
writer.write(json);
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println(Language.getString("ERROR_CONVERT_DATA_OBJECT"));
}
return fileName;
}
The code I used to retrieve the list of events from the JSON file:
public static ArrayList<Event> fromJson(String fileName) {
ArrayList<Event> list = new ArrayList<Event>();
try {
Gson gson = new Gson();
Event[] myTypes = gson.fromJson(new FileReader(fileName),
Event[].class);
for (int i = 0; i < myTypes.length; i++) {
list.add(i, myTypes[i]);
}
} catch (JsonSyntaxException e) {
e.printStackTrace();
} catch (JsonIOException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
System.out
.println(Language.getString("ERROR_MISSING_DEFAULT_FILE"));
}
return list;
}
The Event class:
public class Event {
protected String title;
protected String eventId;
protected String eventDescription;
protected boolean completed;
//
public Event() {
setEventId();
completed = false;
}
//
public String getEventId() {
return eventId;
}
public void setEventId() {
this.eventId=Utilities.generateUniqueIdentification();
}
//
public String getEventDescription() {
return eventDescription;
}
public void setEventDescription(String eventDescription) {
this.eventDescription = eventDescription;
}
//
public boolean getCompleted() {
return completed;
}
//
public void setCompleted() {
completed = true;
}
//
public void setUncompleted() {
completed = false;
}
//
/**
* This method returns the title of an event.
* #return Returns event title.
*/
public String getTitle() {
return title;
}
//
/**
* This method sets the title of an event.
* #param title The title of this event.
*/
public void setTitle(String title) {
this.title = title;
}
}
The TimedEvent class:
import java.util.Calendar;
public class TimedEvent extends Event {
protected Calendar eventStartDateTime;
protected Calendar eventEndDateTime;
public TimedEvent(String title, Calendar eventStartDateTime,
Calendar eventEndDateTime) {
super();
this.title = title;
this.eventStartDateTime = eventStartDateTime;
this.eventEndDateTime = eventEndDateTime;
}
public Calendar getEventStartDateTime() {
return eventStartDateTime;
}
public void setEventStartDateTime(Calendar eventStartDateTime) {
this.eventStartDateTime = eventStartDateTime;
}
public Calendar getEventEndDateTime() {
return eventEndDateTime;
}
public void setEventEndDateTime(Calendar eventEndDateTime) {
this.eventEndDateTime = eventEndDateTime;
}
}
The FloatingEvent class:
public class FloatingEvent extends Event{
//
public FloatingEvent(String title){
super();
setTitle(title);
setEventId();
}
}
You have to call the method toJson only once, by passing a list of Events that contains objects that can be either TimedEvents or FloatingEvent.
Related
I want to show a district list in a spinner, and i am getting that data through an API.
Here is an example of the response.
{
"districts": [
{
"district": "ANANTNAG"
},
{
"district": "BADGAM"
},
{
"district": "BANDIPORA"
},
{
"district": "BARAMULLA"
},
{
"district": "DODA"
},
{
"district": "GANDERBAL"
},
{
"district": "JAMMU"
},
{
"district": "KARGIL"
},
{
"district": "KATHUA"
},
{
"district": "KISHTWAR"
},
{
"district": "KULGAM"
},
{
"district": "KUPWARA"
},
{
"district": "LEH LADAKH"
},
{
"district": "POONCH"
},
{
"district": "PULWAMA"
},
{
"district": "RAJAURI"
},
{
"district": "RAMBAN"
},
{
"district": "REASI"
},
{
"district": "SAMBA"
},
{
"district": "SHOPIAN"
},
{
"district": "SRINAGAR"
},
{
"district": "UDHAMPUR"
},
{
"district": "JAMMU AND KASHMIR"
}
],
"Request_type": "districts",
"responseCode": "Success"
}
After that, I created 2 schemapojo class for response and dataList as well.
Then, I am calling this into a class but its not working!! I don't have any idea how to call an API and set the response data into a spinner.
Please help
private void getdistricts(String state) {
JSONObject mJobj = new JSONObject();
try {
mJobj.put("state", state);
mJobj.put(REQUEST, "districts");
} catch (JSONException e) {
e.printStackTrace();
}
Call<districtresponse> call = RetrofitClient.getInstance().getApi().getDistrict(mJobj);
call.enqueue(new Callback<districtresponse>() {
#Override
public void onResponse(Call<districtresponse> call, Response<districtresponse> response) {
String status = response.body().getResponseCode();
if (status.equalsIgnoreCase("Success")){
district_list = response.body().getDistricts();
districts = new ArrayAdapter<String>(this,R.layout.dist_list,district_list);
}
}
#Override
public void onFailure(Call<districtresponse> call, Throwable t) {
}
});
}
Here in code district_List variable is for a second model class where all district List is available.
I tried a different process from youtube but none of that worked !!
Change code
districts = new ArrayAdapter<String>(this,R.layout.dist_list,district_list);
To this
ArrayAdapter adapter
= new ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
districts);
// set simple layout resource file
// for each item of spinner
adapter.setDropDownViewResource(
android.R.layout
.simple_spinner_dropdown_item);
// Set the ArrayAdapter (ad) data on the
// Spinner which binds data to spinner
spino.setAdapter(adapter);
You can also try like this
ArrayList<String> stringArrayList = null; //Create A global Variable
Call<Example> call = RetrofitClient.getInstance().getApi().getDistrict();
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
if (response.code() == 200) {
ArrayList<District> districts = (ArrayList<District>) response.body().getDistricts();
for (int i = 0; i < districts.size(); i++) {
stringArrayList.add(districts.get(i).getDistrict());
}
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
}
});
ArrayAdapter arrayAdapter = new ArrayAdapter(this,R.layout.dist_list,district_list,stringArrayList);
arrayAdapter.setDropDownViewResource(R.layout.dist_list,district_list);
yourSpinner.setAdapter(arrayAdapter);
And here create a model like this
Example Model Class
public class Example {
#SerializedName("districts")
#Expose
private List<District> districts = null;
#SerializedName("Request_type")
#Expose
private String requestType;
#SerializedName("responseCode")
#Expose
private String responseCode;
public List<District> getDistricts() {
return districts;
}
public void setDistricts(List<District> districts) {
this.districts = districts;
}
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getResponseCode() {
return responseCode;
}
public void setResponseCode(String responseCode) {
this.responseCode = responseCode;
}
}
District Model Class
public class District {
#SerializedName("district")
#Expose
private String district;
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
}
I just hope your problem is solved using this
I created an android application to handle network requests using Volley API. I have managed to get a response from the server but I am failing to loop through the different objects of the result JSON and when I add data to a Listview it is only giving me the application's package name with a number added at the end.
This is the response that I want to handle.
{
"list": [
{
"dt": 1637172000,
"main": {
"temp": 301.79,
"feels_like": 300.34,
"temp_min": 298.24,
"temp_max": 301.79,
"pressure": 1008,
"sea_level": 1008,
"grnd_level": 854,
"humidity": 20,
"temp_kf": 3.55
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01n"
}
],
"clouds": {
"all": 7
},
"wind": {
"speed": 3.77,
"deg": 46,
"gust": 8.98
},
"visibility": 10000,
"pop": 0,
"sys": {
"pod": "n"
},
"dt_txt": "2021-11-17 18:00:00"
}
]
}
The object model and its fields
public class WeatherReportModel {
private int dt;
private JSONObject main;
private JSONArray weather;
private JSONObject clouds;
private JSONObject wind;
private int visibility;
private double pop;
private JSONObject sys;
private String dt_txt;
public WeatherReportModel(
int dt,
JSONObject main,
JSONArray weather,
JSONObject clouds,
JSONObject wind,
int visibility,
double pop,
JSONObject sys,
String dt_txt) {
this.dt = dt;
this.main = main;
this.weather = weather;
this.clouds = clouds;
this.wind = wind;
this.visibility = visibility;
this.pop = pop;
this.sys = sys;
this.dt_txt = dt_txt;
}
}
This is call back function which fetches the responses and add to the Model's object
public void getWeather(VolleyResponseListener forecast) {
List<WeatherReportModel> weatherReportModels = new ArrayList<>();
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray weather_list = response.getJSONArray("list");
// get the first item
for (int i = 0; i < weather_list.length(); i++) {
WeatherReportModel one_day_weather = new WeatherReportModel();
JSONObject first_day_from_api = (JSONObject) weather_list.get(i);
one_day_weather.setDt(first_day_from_api.getInt("dt"));
one_day_weather.setMain(first_day_from_api.getJSONObject("main"));
one_day_weather.setWeather(first_day_from_api.getJSONArray("weather"));
one_day_weather.setClouds(first_day_from_api.getJSONObject("clouds"));
one_day_weather.setWind(first_day_from_api.getJSONObject("wind"));
one_day_weather.setVisibility(first_day_from_api.getInt("visibility"));
one_day_weather.setPop(first_day_from_api.getLong("pop"));
one_day_weather.setSys(first_day_from_api.getJSONObject("sys"));
one_day_weather.setDt_txt(first_day_from_api.getString("dt_txt"));
weatherReportModels.add(one_day_weather);
}
forecast.onResponse(weatherReportModels);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//get the property call consolidated weather
MySingleton.getInstance(context).addToRequestQueue(request);
}
Usually, ArrayAdapter when used like this will try to use toString() function to get the value and display it. Try to override the toString in the
WeatherReportModel and try again.
{
"response_code": 200,
"debit": 3,
"position": "Train has reached Destination and late by 5 minutes",
"train": {
"number": "12046",
"name": "CDG NDLS SHTBDI"
},
"route": [
{
"no": 1,
"day": 0,
"station": {
"name": "CHANDIGARH",
"code": "CDG"
},
"has_arrived": false,
"has_departed": true,
"distance": 0,
"scharr": "Source",
"schdep": "12:00",
"actarr": "00:00",
"actdep": "12:00",
"scharr_date": "19 Nov 2015",
"actarr_date": "19 Nov 2015",
"latemin": 0
},
{
"no": 2,
"day": 0,
"station": {
"name": "AMBALA CANT JN",
"code": "UMB"
},
"has_arrived": true,
"has_departed": true,
"distance": 67,
"scharr": "12:40",
"schdep": "12:42",
"actarr": "12:40",
"actdep": "12:42",
"scharr_date": "19 Nov 2015",
"actarr_date": "19 Nov 2015",
"latemin": 0
},
{
"no": 3,
"day": 0,
"station": {
"name": "NEW DELHI",
"code": "NDLS"
},
"has_arrived": true,
"has_departed": false,
"distance": 265,
"scharr": "15:25",
"schdep": "Destination",
"actarr": "15:30",
"actdep": "00:00",
"scharr_date": "19 Nov 2015",
"actarr_date": "19 Nov 2015",
"latemin": 5
}
]
}
public class TrainStatus {
public static int responseCode;
private int serialNo;
private String scheduleArrival;
private String actualArrival;
public static String station;
public static int debit;
private String statusOfArrival;
private boolean hasArrived;
private boolean hasDeparted;
private int latemin;
private String actualArrivalDate;
private String scheduleArrivalDate;
public static String position;
public String name;
public String getName()
{
return getName();
}
public void setName(String name)
{
this.name=name;
}
public boolean isHasArrived()
{
return hasArrived;
}
public void setHasArrived(boolean hasArrived)
{
this.hasArrived = hasArrived;
}
public boolean isHasDeparted()
{
return hasDeparted;
}
public void setHasDeparted(boolean hasDeparted)
{
this.hasDeparted = hasDeparted;
}
public int getLatemin()
{
return latemin;
}
public void setLatemin(int latemin)
{
this.latemin = latemin;
}
public void setSerialNo(int serialNo)
{
this.serialNo = serialNo;
}
public String getScheduleArrival()
{
return scheduleArrival;
}
public void setScheduleArrival(String scheduleArrival)
{
this.scheduleArrival = scheduleArrival;
}
public String getActualArrival()
{
return actualArrival;
}
public void setActualArrival(String actualArrival)
{
this.actualArrival = actualArrival;
}
public String getStation()
{
return station;
}
public void setStation(String station)
{
this.station = station;
}
public String getStatusOfArrival()
{
return statusOfArrival;
}
public void setStatusOfArrival(String statusOfArrival)
{
this.statusOfArrival = statusOfArrival;
}
public String getActualArrivalDate()
{
return actualArrivalDate;
}
public void setActualArrivalDate(String actualArrivalDate)
{
this.actualArrivalDate = actualArrivalDate;
}
public String getScheduleArrivalDate()
{
return scheduleArrivalDate;
}
public void setScheduleArrivalDate(String scheduleArrivalDate)
{
this.scheduleArrivalDate = scheduleArrivalDate;
}
}
public class TrainStatusParser {
public static List<TrainStatus> parseFeed(String content){
try
{
JSONObject jsonObject = new JSONObject(content);
List<TrainStatus> trainList = new ArrayList<>();
TrainStatus.responseCode = jsonObject.getInt("response_code");
TrainStatus.position = jsonObject.getString("position");
TrainStatus.debit=jsonObject.getInt("debit");
JSONArray route = jsonObject.getJSONArray("route");
for(int i=0;i<route.length();i++)
{
JSONObject routeObject = route.getJSONObject(i);
TrainStatus trainStatus = new TrainStatus();
if (jsonObject.has("station"))
{
JSONObject addressObject = jsonObject.getJSONObject("station");
trainStatus.name=addressObject.getString("name");
}
trainStatus.setSerialNo(routeObject.getInt("no"));
trainStatus.setScheduleArrival(routeObject.getString("scharr"));
trainStatus.setActualArrival(routeObject.getString("actarr"));
trainStatus.setStatusOfArrival(routeObject.getString("status"));
trainStatus.setHasArrived(routeObject.getBoolean("has_arrived"));
trainStatus.setHasDeparted(routeObject.getBoolean("has_departed"));
trainStatus.setLatemin(routeObject.getInt("latemin"));
trainStatus.setActualArrivalDate(routeObject.getString("actarr_date"));
trainStatus.setScheduleArrivalDate(routeObject.getString("scharr_date"));
trainList.add(trainStatus);
}
return trainList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}
Everything is correctly fetched except station name
Try this following code.
for(int i=0;i<route.length();i++) {
JSONObject routeObject = route.getJSONObject(i);
TrainStatus trainStatus = new TrainStatus();
JSONObject jsonObject_station = routeObject.getJSONObject("station");
String stationname = jsonObject_station.getString("name");
String code = jsonObject_station.getString("code");
Log.d("checkvalue", " " + stationname + " " + code);
trainStatus.setSerialNo(routeObject.getInt("no"));
trainStatus.setScheduleArrival(routeObject.getString("scharr"));
trainStatus.setActualArrival(routeObject.getString("actarr"));
trainStatus.setStatusOfArrival(routeObject.getString("status"));
trainStatus.setHasArrived(routeObject.getBoolean("has_arrived"));
trainStatus.setHasDeparted(routeObject.getBoolean("has_departed"));
trainStatus.setLatemin(routeObject.getInt("latemin"));
trainStatus.setActualArrivalDate(routeObject.getString("actarr_date"));
trainStatus.setScheduleArrivalDate(routeObject.getString("scharr_date"));
trainList.add(trainStatus);
}
Use a library from Google call GSON
In your posted code for parsing each route, you have this:
JSONObject routeObject = route.getJSONObject(i);
TrainStatus trainStatus = new TrainStatus();
if (jsonObject.has("station"))
{
JSONObject addressObject = jsonObject.getJSONObject("station");
trainStatus.name=addressObject.getString("name");
}
Looks like a typo here is causing your problems. You're calling jsonObject.has("station") when you should instead be calling routeObject.has("station"). Similarly, inside the if statement you should change jsonObject.getJSONObject("station") to routeObject.getJSONObject("station").
I am trying to parse a JSON into Java Bean using Jackson.
Snippet of JSON on Server Side:
{
"count": 17,
"next": null,
"previous": null,
"results": [
{
"resource_uri": "http://www.randomsite.com/api/1/personalize/qna/17/",
"answer_set": [],
"answers_count": 0,
"tags": [
"Others"
],
"title": "How many boys hostels are there is ACMS , which one is the best one",
"desc": "How many boys hostel are there in ACMS and which one is good among them, How can i get them, Do i have to apply early or can apply any any time in session. ",
"status": 1,
"is_spam": false,
"upvotes": 0,
"downvotes": 0,
"view_count": 4,
"uri_slug": "how-many-boys-hostels-are-there-is-acms-which-one-is-the-best-one",
"added_on": "2015-06-05T16:43:26",
"user": "http://www.randomsite.com/api/1/users/1/",
"degree": null,
"stream": "http://www.randomsite.com/api/1/streams/16/",
"institute": null,
"course": null,
"city": null,
"state": null
},
{
"resource_uri": "http://www.randomsite.com/api/1/personalize/qna/18/",
"answer_set": [
{
"id": 5,
"resource_uri": "http://www.randomsite.com/api/1/personalize/answers/5/",
"question": "http://www.randomsite.com/api/1/personalize/qna/18/",
"answer_text": "You will get purified water, volley ball court, cricket ground, gymnasium, tt, carrom , chess, parking, mess, canteen",
"status": 1,
"is_spam": false,
"upvotes": 0,
"downvotes": 0,
"best_answer": false,
"added_on": "2015-06-05T17:00:26",
"user": "http://www.randomsite.com/api/1/users/1/"
},
{
"id": 6,
"resource_uri": "http://www.randomsite.com/api/1/personalize/answers/6/",
"question": "http://www.randomsite.com/api/1/personalize/qna/18/",
"answer_text": "You can call your friends over there but girls are not allowed.",
"status": 1,
"is_spam": false,
"upvotes": 0,
"downvotes": 0,
"best_answer": false,
"added_on": "2015-06-05T17:00:26",
"user": "http://www.randomsite.com/api/1/users/1/"
}
],
"answers_count": 2,
"tags": [],
"title": "Girls are allowed in boys hostels of ACMS",
"desc": "If I manage to get Boys hostel in ACMS what are the faciclities that i will get, can i call my friends there which include girls.",
"status": 1,
"is_spam": false,
"upvotes": 0,
"downvotes": 2,
"view_count": 106,
"uri_slug": "girls-are-allowed-in-boys-hostels-of-acms",
"added_on": "2015-06-05T16:43:53",
"user": "http://www.randomsite.com/api/1/users/1/",
"degree": null,
"stream": null,
"institute": null,
"course": null,
"city": null,
"state": null
}
}
This is the Questions Entity class:
public class QnAQuestions implements Parcelable {
public static final Creator<QnAQuestions> CREATOR = new Creator<QnAQuestions>() {
#Override
public QnAQuestions createFromParcel(Parcel source) {
return new QnAQuestions(source);
}
#Override
public QnAQuestions[] newArray(int size) {
return new QnAQuestions[size];
}
};
public String resource_uri;
public ArrayList<QnAAnswers> answer_set;
public int answers_count;
public ArrayList<String> tags;
public String title;
public String desc;
public int status;
public boolean is_spam;
public int upvotes;
public int downvotes;
public int view_count;
public String uri_slug;
public String added_on;
public String user;
public String degree;
public String stream;
public String institute;
public String course;
public String city;
public String state;
public QnAQuestions() {
//answer_set = new ArrayList<QnAAnswers>();
}
public QnAQuestions(Parcel source) {
resource_uri = source.readString();
answers_count = source.readInt();
title = source.readString();
desc = source.readString();
status = source.readInt();
tags = source.createStringArrayList();
is_spam = source.readString() == "true";
upvotes = source.readInt();
downvotes = source.readInt();
view_count = source.readInt();
uri_slug = source.readString();
added_on = source.readString();
user = source.readString();
degree = source.readString();
stream = source.readString();
institute = source.readString();
course = source.readString();
city = source.readString();
state = source.readString();
//answer_set = new ArrayList<QnAAnswers>();
answer_set = source.createTypedArrayList(QnAAnswers.CREATOR);
source.readTypedList(answer_set, QnAAnswers.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(resource_uri);
dest.writeInt(answers_count);
dest.writeString(title);
dest.writeString(desc);
dest.writeInt(status);
dest.writeStringList(tags);
dest.writeInt(is_spam ? 1 : 0);
dest.writeInt(upvotes);
dest.writeInt(downvotes);
dest.writeInt(view_count);
dest.writeString(uri_slug);
dest.writeString(added_on);
dest.writeString(user);
dest.writeString(degree);
dest.writeString(stream);
dest.writeString(institute);
dest.writeString(city);
dest.writeString(state);
dest.writeTypedList(answer_set);
}
}
And this is Answers Class:
public class QnAAnswers implements Parcelable {
public static final Creator<QnAAnswers> CREATOR = new Creator<QnAAnswers>() {
#Override
public QnAAnswers createFromParcel(Parcel source) {
return new QnAAnswers(source);
}
#Override
public QnAAnswers[] newArray(int size) {
return new QnAAnswers[size];
}
};
public long id;
public String resource_uri;
public String question;
public String answer_text;
public int status;
public boolean is_spam;
public int upvotes;
public int downvotes;
public boolean best_answer;
public String added_on;
public String user;
public QnAAnswers() {}
public QnAAnswers(Parcel source) {
id = source.readLong();
resource_uri = source.readString();
question = source.readString();
answer_text = source.readString();
status = source.readInt();
is_spam = source.readString() == "true";
upvotes = source.readInt();
downvotes = source.readInt();
best_answer = source.readString() == "true";
added_on = source.readString();
user = source.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeString(resource_uri);
dest.writeString(question);
dest.writeString(answer_text);
dest.writeInt(status);
dest.writeInt(is_spam ? 1 : 0);
dest.writeInt(upvotes);
dest.writeInt(downvotes);
dest.writeInt(best_answer ? 1 : 0);
dest.writeString(added_on);
dest.writeString(user);
}
}
I am only able to see the fields pertaining to QnAAnswers Class. All other fields are not populated.
This is the code in the activity which parses the API response and displays the QnAFragment:
private void showQnAQuestions(String response) {
try {
String questions = extractResults(response);
List<QnAQuestions> qnAQuestions = JSON.std.listOfFrom(QnAQuestions.class, questions);
displayFragment(QnAQuestionsListFragment.newInstance(new ArrayList<>(qnAQuestions)), false);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
private String extractResults(String response) {
try {
// JsonFactory jf = new JsonFactory();
//Result r = Result.createFromJson(jf.createParser(json2));
Map<String, Object> map = JSON.std.mapFrom(response);
if (map.get("next") != null)
next = map.get("next").toString();
else
next = null;
return JSON.std.asString(map.get("results"));
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
return null;
}
Any pointers would do great help!!
First thing I noticed, you read:
is_spam = source.readString() == "true"
but you write is_spam as 1 or 0 into the Parcel:
dest.writeInt(is_spam ? 1 : 0);
Same for best _ answer.
I am getting an array size of zero for the "tweets" array when trying to access the arraylist that it should be stored in. I am using Jackon databinding to a class, which at this point has "worked" as in not gave any errors or exceptions. But, the problem is still that the array is returning empty.
Here is the method where I am accessing the class that the JSON is being binded to:
WeatherDatabaseCreator.java
//Read in files to be parsed.
for (int i = 0; i < twitterFiles.size(); i++) {
File twitterFile = twitterFiles.get(i);
WeatherTweetParser wtp = new WeatherTweetParser(twitterFile);
wtp.mapJavaObject();
tws = new Tweets();
tweets = tws.getTweets();
System.out.print(tweets.size());
tweetIndex = 0;
System.out.println("Parsing and inserting twitter file '" + twitterFile.getAbsolutePath() + "'...");
//Step through all the tweets in each file, using the TweetParser class.
while (true) {
tweet = tweets.get(tweetIndex);
user = tweet.new User();
entity = tweet.new Entities();
userMentions = entity.getUserMentions();
hashtags = entity.getHashtags();
if (tweet.getText() == null) {
break;
}
numParsed++;
Boolean success = wdbm.insertTweet(tweet, user);
if (success == true) {
numInserted++;
}
if (entity.getNumHashtags() > 0){
for (int j = 0; j < entity.getNumHashtags(); j++) {
wdbm.insertHashtag(tweet, hashtags.get(j));
}
}
if (entity.getNumUserMentions() > 0) {
for (int k = 0; k < entity.getNumUserMentions(); k++) {
wdbm.insertReference(tweet, userMentions.get(k));
}
}
if (numParsed % UPDATE_INTERVAL == 0) {
System.out.println(numParsed + " tweets parsed. " + numInserted + " tweets inserted into database...");
}
tweetIndex++;
}
Here is part of the JSON File. The file is made up of an array of tweets, with some nested classes. Here I included two elements of the array:
2014-01-03-11-03.terms.json
{
"tweets": [
{
"filter_level": "medium",
"contributors": null,
"text": "U know your ice fishing at home when ur snacks are sandwiches,chips,dips,beef jerky and all the goodies instead of just a case of beer #mom",
"geo": null,
"retweeted": false,
"in_reply_to_screen_name": null,
"truncated": false,
"lang": "en",
"entities": {
"symbols": [
],
"urls": [
],
"hashtags": [
{
"text": "mom",
"indices": [
135,
139
]
}
],
"user_mentions": [
]
},
"in_reply_to_status_id_str": null,
"id": 419137025376145408,
"source": "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone<\/a>",
"in_reply_to_user_id_str": null,
"favorited": false,
"in_reply_to_status_id": null,
"retweet_count": 0,
"created_at": "Fri Jan 03 16:03:48 +0000 2014",
"in_reply_to_user_id": null,
"favorite_count": 0,
"id_str": "419137025376145408",
"place": null,
"user": {
"location": "",
"default_profile": false,
"profile_background_tile": true,
"statuses_count": 5411,
"lang": "en",
"profile_link_color": "17EBCF",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/408240224/1384838946",
"id": 408240224,
"following": null,
"protected": false,
"favourites_count": 4222,
"profile_text_color": "333333",
"description": "It is what it is, no more, no less. Trust in the Lord. BSU Softball #5. My whole being is happy - Psalm 16:9",
"verified": false,
"contributors_enabled": false,
"profile_sidebar_border_color": "FFFFFF",
"name": "Nicole Anne",
"profile_background_color": "C0DEED",
"created_at": "Wed Nov 09 05:03:58 +0000 2011",
"default_profile_image": false,
"followers_count": 452,
"profile_image_url_https": "https://pbs.twimg.com/profile_images/413270299925164033/mWiJBKP2_normal.jpeg",
"geo_enabled": true,
"profile_background_image_url": "http://a0.twimg.com/profile_background_images/698793822/14d9ce538d96b435ad4449d5385a3ec1.jpeg",
"profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/698793822/14d9ce538d96b435ad4449d5385a3ec1.jpeg",
"follow_request_sent": null,
"url": null,
"utc_offset": -32400,
"time_zone": "Alaska",
"notifications": null,
"profile_use_background_image": true,
"friends_count": 634,
"profile_sidebar_fill_color": "DDEEF6",
"screen_name": "NDupay",
"id_str": "408240224",
"profile_image_url": "http://pbs.twimg.com/profile_images/413270299925164033/mWiJBKP2_normal.jpeg",
"listed_count": 1,
"is_translator": false
},
"coordinates": null
},
{
"filter_level": "medium",
"contributors": null,
"text": "Just watched DeBlasio shovel snow for the cameras and I have to say, his form is terrible. Looks a bit inexperienced.",
"geo": null,
"retweeted": false,
"in_reply_to_screen_name": null,
"truncated": false,
"lang": "en",
"entities": {
"symbols": [
],
"urls": [
],
"hashtags": [
],
"user_mentions": [
]
},
"in_reply_to_status_id_str": null,
"id": 419137026458673152,
"source": "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone<\/a>",
"in_reply_to_user_id_str": null,
"favorited": false,
"in_reply_to_status_id": null,
"retweet_count": 0,
"created_at": "Fri Jan 03 16:03:48 +0000 2014",
"in_reply_to_user_id": null,
"favorite_count": 0,
"id_str": "419137026458673152",
"place": null,
"user": {
"location": "",
"default_profile": false,
"profile_background_tile": false,
"statuses_count": 2609,
"lang": "en",
"profile_link_color": "FF8000",
"id": 163686045,
"following": null,
"protected": false,
"favourites_count": 204,
"profile_text_color": "333333",
"description": "Love learning, Hockey #NYR, music and photography. My family is my whole life.",
"verified": false,
"contributors_enabled": false,
"profile_sidebar_border_color": "EEEEEE",
"name": "Steven Marques",
"profile_background_color": "ACDED6",
"created_at": "Wed Jul 07 01:26:25 +0000 2010",
"default_profile_image": false,
"followers_count": 56,
"profile_image_url_https": "https://pbs.twimg.com/profile_images/378800000795958214/5e3ff928282ad692a36e941e5c5ff628_normal.jpeg",
"geo_enabled": false,
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme18/bg.gif",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme18/bg.gif",
"follow_request_sent": null,
"url": null,
"utc_offset": -18000,
"time_zone": "Eastern Time (US & Canada)",
"notifications": null,
"profile_use_background_image": true,
"friends_count": 58,
"profile_sidebar_fill_color": "F6F6F6",
"screen_name": "SMGafanha",
"id_str": "163686045",
"profile_image_url": "http://pbs.twimg.com/profile_images/378800000795958214/5e3ff928282ad692a36e941e5c5ff628_normal.jpeg",
"listed_count": 2,
"is_translator": false
},
"coordinates": null
},
Here is the Java class that the JSON file is mapped to, followed by the class mapping the JSON to the class:
Tweets.java
public class Tweets {
private ArrayList<Tweet> tweets;
public Tweets() {
tweets = new ArrayList<Tweet>();
}
public ArrayList<Tweet> getTweets() {
return tweets;
}
public void setTweets(ArrayList<Tweet> tweets) {
this.tweets = tweets;
}
public static class Tweet {
private String text;
#JsonProperty("source")
private String postMethod;
#JsonProperty("created_at")
private String time;
#JsonProperty("id")
private String ID;
public Tweet() {
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public String getPostMethod() {
return postMethod;
}
public void setPostMethod(String postMethod) {
this.postMethod = postMethod;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public class User {
private String location;
#JsonProperty("screen_name")
private String user;
#JsonProperty("time_zone")
private String timeZone;
#JsonProperty("description")
private String accountDescription;
public User(){
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getAccountDescription() {
return accountDescription;
}
public void setAccountDescription(String accountDescription) {
this.accountDescription = accountDescription;
}
}
public class Entities {
#JsonProperty("user_mentions")
ArrayList<UserMention> userMentions;
#JsonProperty("hashtags")
ArrayList<Hashtag> hashtags;
public Entities() {
}
public ArrayList<UserMention> getUserMentions() {
return userMentions;
}
public int getNumUserMentions() {
return userMentions.size();
}
public UserMention getUserMention(int index) {
return userMentions.get(index);
}
public void setUserMentions(ArrayList<UserMention> userMentions) {
this.userMentions = userMentions;
}
public ArrayList<Hashtag> getHashtags() {
return hashtags;
}
public int getNumHashtags() {
return hashtags.size();
}
public Hashtag getHashtag(int index) {
return hashtags.get(index);
}
public void setHashtags(ArrayList<Hashtag> hashtags) {
this.hashtags = hashtags;
}
public class UserMention {
#JsonProperty("screen_name")
private String userRef;
public UserMention() {
}
public String getUserRef() {
return userRef;
}
public void setUserRef(String userRef) {
this.userRef = userRef;
}
}
public class Hashtag {
#JsonProperty("text")
private String hashText;
public Hashtag() {
}
public String getHashText() {
return hashText;
}
public void setHashText(String hashText) {
this.hashText = hashText;
}
}
}
}
}
WeatherTweetParser.java
public class WeatherTweetParser {
private static File twitterFile;
public WeatherTweetParser(File twitterFile) {
WeatherTweetParser.twitterFile = twitterFile;
}
public void mapJavaObject() {
String jsonFile = twitterFile.getName();
System.out.println("Mapping JSON to WeatherTweet Class.");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
mapper.readValue(new File(jsonFile), Tweets.class);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Finished Mapping of JSON File.");
}
And here is the error:
Mapping JSON to WeatherTweet Class.
Finished Mapping of JSON File.
Tweets size: 0
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at database.WeatherDatabaseCreator.main(WeatherDatabaseCreator.java:145)
Parsing and inserting twitter file 'C:\Users\Jared\Documents\Eclipse
WorkSpace\workspace\WeatherDatabaseCreator\2014-01-03-11-03.terms.json'...
On this line of WeatherDatabaseCreator.java:
tweet = tweets.get(tweetIndex);
TL:DR: I understand this error is because the index is out of range, because there is nothing obviously even in the tweets array. But, if the Jackson mapping of the JSON file to my Java Class went through without exceptions, why is the tweets array empty?
while (true) {
tweet = tweets.get(tweetIndex);
user = tweet.new User();
entity = tweet.new Entities();
userMentions = entity.getUserMentions();
hashtags = entity.getHashtags();
if (tweet.getText() == null) {
break;
}
The only break in this loop will work only if getText is null. If getText is not null for all the tweets, you'll get index out of bound exception.
Instead of while(true) you should probably use a check like tweetIndex < tweets.size()
The second problem. You create a Tweets object without loading any items there:
wtp.mapJavaObject();
tws = new Tweets();
tweets = tws.getTweets();
Of course tws object will not have any tweets in this case. What you need to do is to make sure that your mapJavaObjects() method returns a Tweets object with the tweets loaded by ObjectMapper and after this is done your code should look like this:
tweets = wtp.mapJavaObject();
Something like this:
public Tweets mapJavaObject() {
String jsonFile = twitterFile.getName();
Tweets ret = null;
System.out.println("Mapping JSON to WeatherTweet Class.");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
ret = (Tweets) mapper.readValue(new File(jsonFile), Tweets.class);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Finished Mapping of JSON File.");
retrun ret;
}