i want to analyse the json just like:
[{"id":"ssq","name":"双色球","term":"2010092","date":"2010-08-12 19:15","numbers":{"normal":"3,13,19,27,28,30","special":"2"},"jackpot":"30000000"},{"id":"3d","name":"3D","term":"2010216","date":"2010-08-12 19:55","numbers":{"normal":"6,8,8"},"jackpot":"-"},{"id":"qlc","name":"七乐彩","term":"2010093","date":"2010-08-11 20:45","numbers":{"normal":"08,09,10,11,16,21,27","special":"26"},"jackpot":"0"},{"id":"dfljy","name":"东方6+1","term":"2010093","date":"2010-08-14 18:30","numbers":{"normal":"4,1,3,9,7,2","special":"羊"},"jackpot":"12866531"},{"id":"swxw","name":"15选5","term":"2010217","date":"2010-08-12 18:45","numbers":{"normal":"1,3,5,13,15"},"jackpot":"5693612"},{"id":"ssl","name":"时时乐","term":"20100811-23","date":"2010-08-12 10:27","numbers":{"normal":"6,7,1"},"jackpot":"-"},{"id":"klsf","name":"快乐十分","term":"201021649","date":"2010-08-11 22:00","numbers":{"normal":"5,11,12,14,20"},"jackpot":"-"},{"id":"klsc","name":"快乐双彩","term":"2010215","date":"2010-08-10 21:25","numbers":{"normal":"12,23,10,15,7,3","special":"11"} ,"jackpot":"198059"}]
i want to gain all of them,but the data is so many,so whether i need to create 8 kinds of class to store the data,so to be easier to use.thanks!
To add to cfei's response, one thing that I've done when processing JSON responses from Flickr, is create a new class particularly for that type of object.
So for yours, just playing it by ear, something like the below:
public class Lottery() {
private JSONObject json;
private String id;
private String name;
private String term;
private String date;
private String norm_numbers;
private String spec_numbers;
private String jackpot;
public Lottery(JSONObject json) {
this.json = json;
}
public void setId()
{
try {
id = json.getString("id");
} catch (JSONException e) {
id = "";
}
}
//additional getters and setters, etc.
}
This way, you can make an array of objects, and access the fields like so:
//...get a JSONObject from the array...
Lottery lottery = new Lottery(json);
Log.v("ID", lottery.id);
Log.v("Name", lottery.name);
and so on.
Do you mean that you want to iterate through each of the eight JSONObjects in this JSONArray? You need to create a JSONArray object with the input string you posed above (let's call it "response", as used below) and then iterate through the array to get each JSONObject it contains. For example:
JSONArray array = new JSONArray(response);
for(int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
// do something with obj
// example: to get the id for a particular object, use obj.getString("id")
Log.i("Example", "the id is"+obj.getString("id"));
}
Related
I have a nested JSON array from which I need to retrieve values of all Usernames nested within Friends.
{
"Friends": [
{"Username": "abc"},
{"Username": "xyz"}
]
}
After I get all the usernames, I want to store it in a List that I will use with an adapter and ListView.
FriendList.java:
public class FriendList
{
#SerializedName("Username")
private String username;
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
This is the code that I have written so far:
if (httpResult != null && !httpResult.isEmpty()) //POST API CALL
{
Type listType = new TypeToken<List<FriendList>>() {}.getType();
List<FriendList> friendList = new Gson().fromJson(httpResult, listType);
FLCustomAdapter adapter = new FLCustomAdapter(getActivity(), friendList);
mainFriendsListView.setAdapter(adapter);
}
However, an error occurs: Failed to deserialize Json object.
Please suggest, what additions/changes should be made to it, so that I can retrieve nested JSON values into a list?
First of all, You have to understand the strucure of this Json.
You can see, it contains
1 . A json object
2 . This json object contains a json array which can include several different json objects or json arrays.
In this case, it contains json objects.
Parsing:
Get the Json Object first
try{
JSONObject jsonObject=new JSONObject(jsonResponse);
if(jsonObject!=null){
//get the json array
JSONArray jsonArray=jsonObject.getJSONArray("Friends");
if(jsonArray!=null){
ArrayList<FriendList> friendList=new ArrayList<FriendList>();
//iterate your json array
for(int i=0;i<jsonArray.length();i++){
JSONObject object=jsonArray.getJSONObject(i);
FriendList friend=new FriendList();
friend.setUserName(object.getString(Username));
friendList.add(friend);
}
}
}
}
catch(JSONException ex){
ex.printStackTrace();
}
hope, it will help you.
Solution with GSON.
You need to two class to parse this.
FriendList and UsernameDao.
public class UsernameDao {
#SerializedName("Username")
private String username;
//get set methods
}
Simple Json Parsing would be like this
JSONObject params=new JSONObject(httpResult);
JSONObject params1=params.getJsonObject("Friends");
JsonArray array=params1.getJsonArray();
for(int i=0;i<array.length();i++)
{
String userName=array.getJsonObject(i).getString("UserName");
// Do whatever you want to do with username
}
Following code works good without any use of GSON , Please try .
String jsonString = "Your Json Data";
JSONObject jsonRootObject = new JSONObject(jsonString );
JSONArray friendsArray = jsonRootObject .getJSONArray("Friends");
ArrayList<FriendList > friendsList = new ArrayList<FriendList >();
for(int friendsLen = 0 ;friendsLen < friendsArray .length() ; friendsLen ++){
FriendList userNameObj = new UserName();
JSONObject jsonObj = jsonRootObject.getJSONObject(friendsLen ) ;
String Username = jsonObj.getString("Username");
userNameObj .setUserName(Username );
friendsList .add(userNameObj );
}
Now friendsList the list which you want .
List<FriendList> friendList = new Gson().fromJson(httpResult, listType);
This cannot work because it expects your whole JSON document to be just an array of FriendList element (by the way, why "FriendList"?): [{"Username": "abc"},{"Username": "xyz"}] -- this is what can be parsed by your approach.
The easiest solution to fix this (apart from harder to implement but more efficient streamed reading in order to peel of possible unnecessary properties) is just creating a correct mapping:
final class Wrapper {
#SerializedName("Friends")
final List<Friend> friends = null;
}
final class Friend {
#SerializedName("Username")
final String username = null;
}
Now deserialization is trivial and you don't have to define a type token because Gson has enough information for the type from the Wrapper.friends field:
final Wrapper wrapper = gson.fromJson(response, Wrapper.class);
for ( final Friend friend : wrapper.friends ) {
System.out.println(friend.username);
}
Output:
abc
xyz
Change List<FriendList> friendList = new Gson().fromJson(httpResult, listType);
to
FriendList friends = new Gson().fromJson(httpResult, listType);
List<Friend> friends = friends.list;
Updated FriendList.java as mentioned below
FriendList.java
public class FriendList
{
#SerializedName("Friends")
public List<Friend> list;
}
Friend.java
public class Friend
{
#SerializedName("Username")
private String username;
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
For learning purposes i'm creating an android app by using Realm and the Edinburg Festival Api. It's going pretty well except for one problem.
I'm using the following to convert the retrieved JSON to RealmObjects:
public void onResponse(final String response) {
realm.executeTransactionAsync(new Realm.Transaction(){
#Override
public void execute(Realm realm) {
// Update our realm with the results
parseImages();
realm.createOrUpdateAllFromJson(Festival.class, response);
}
}
}
This works fine except for one field, the images. The image part of the JSON:
"images": {
"031da8b4bad1360eddea87e8820615016878b183": {
"hash": "031da8b4bad1360eddea87e8820615016878b183",
"orientation": "landscape",
"type": "hero",
"versions": {
"large-1024": {
"height": 213,
"mime": "image/png",
"type": "large-1024",
}
"width": 1024
}
}
The problem here is the hash inside the image object. I have no clue how to handle this. The hash is different for every festival. Would it be possible to to make a custom JSON deserializer in my RealmObject?
Last code sample is my current model:
public class Festival extends RealmObject {
#PrimaryKey
public String title;
RealmList<Image> images;
public String description_teaser;
public String description;
public String genre;
public String age_category;
public String website;
public RealmList<Performance> performances;
public int votes;
}
I'm aware my PK is not optimal but this is still just testing to get the images working and i needed to set a PK for migrating.
Any tips are welcome, cheers :)
Update
Added the image model:
public class Image extends RealmObject {
public String hash;
public String orientation;
public String type;
RealmList<Version> versions;
}
Update 2
My attempt to parse the images before calling realm.createOrUpdateAllFromJson(Festival.class, response);
private void parseImages(String jsonString) throws JSONException {
JSONArray jsonArr = new JSONArray(jsonString);
for(int i = 0; i < jsonArr.length(); i++){
JSONObject jsonObj = jsonArr.getJSONObject(i);
JSONObject images = (JSONObject)jsonObj.get("images");
Iterator<String> iter = images.keys();
while (iter.hasNext()) {
String key = iter.next();
try {
JSONObject value = json.get(key);
realm.createOrUpdateObjectFromJson(Image.class,value);
} catch (JSONException e) {
// Something went wrong!
}
}
}
}
Update 3
I created a function that cleans up the broken JSON i get from the API. It ain't very nice but it works for now. it removes the hashes and the wierd versions and just places them both in a array. I'm sure it could be more efficiently written but i'll just go with this so i can move on with the rest of my app for now. See my own answer.
my own temporary solution:
/**
* Function to fix the json coming from the Festival API
* This is a bit more complicated then it needs to be but realm does not yet support #Serializedname
* It removes the "large-1024" (and simllar) object and places the versions in a JSON version array
* Then it removes the hashes and creates and images array. The JsonArray can now be parsed normally :)
*
* #param jsonString Result string from the festival api
* #return JSONArray The fixed JSON in the form of a JSONArray
* #throws JSONException
*/
private JSONArray cleanUpJson(String jsonString) throws JSONException {
JSONArray json = new JSONArray(jsonString);
for(int i = 0; i < json.length(); i++){
// We store the json Image Objects in here so we can remove the hashes
Map<String,JSONObject> images = new HashMap<>();
JSONObject festivalJson = json.getJSONObject(i);
JSONObject imagesJson = (JSONObject)festivalJson.get("images");
// Iterate each hash inside the images
Iterator<String> hashIter = imagesJson.keys();
while (hashIter.hasNext()) {
String key = hashIter.next();
try {
final JSONObject image = imagesJson.getJSONObject(key);
// Remove the version parents and map them to version
Map<String, JSONObject> versions = new HashMap<>();
JSONObject versionsJsonObject = image.getJSONObject("versions");
// Now iterate all the possible version and map add to the hashmap
Iterator<String> versionIter = versionsJsonObject.keys();
while(versionIter.hasNext()){
String currentVersion = versionIter.next();
versions.put(currentVersion,versionsJsonObject.getJSONObject(currentVersion));
}
// Use the hashmap to modify the json so we get an array of version
// This can't be done in the iterator because you will get concurrent error
image.remove("versions");
Iterator hashMapIter = versions.entrySet().iterator();
JSONArray versionJsonArray = new JSONArray();
while( hashMapIter.hasNext() ){
Map.Entry pair = (Map.Entry)hashMapIter.next();
versionJsonArray.put(pair.getValue());
}
image.put("versions",versionJsonArray);
Log.d(LOG_TAG,image.toString());
} catch (JSONException e) {
e.printStackTrace();
}
images.put(key,imagesJson.getJSONObject(key));
}
// Now let's get rid of the hashes
Iterator hashMapIter = images.entrySet().iterator();
JSONArray imagesJsonArray = new JSONArray();
while( hashMapIter.hasNext() ){
Map.Entry pair = (Map.Entry)hashMapIter.next();
imagesJsonArray.put(pair.getValue());
}
festivalJson.put("images", imagesJsonArray);
}
return json;
}
Hope it helps someone :) But sure ain't neat.
Due to how the keys are dynamic in this JSON (why isn't this an array? Whoever designed this API had no idea what they were doing), you'll have to manually parse the object up to the point of the hash key:
JSONObject jsonObj = new JSONObject(jsonString);
JSONObject images = (JSONObject)jsonObj.get("images");
Iterator<String> iter = images.keys();
while (iter.hasNext()) {
String key = iter.next();
try {
JSONObject value = json.get(key);
realm.createOrUpdateObjectFromJson(Image.class, value.toString());
} catch (JSONException e) {
// Something went wrong!
}
}
I've a json output which returns something like this :
[
{
"title":"facebook",
"description":"social networking website",
"url":"http://www.facebook.com"
},
{
"title":"WoW",
"description":"game",
"url":"http://us.battle.net/wow/"
},
{
"title":"google",
"description":"search engine",
"url":"http://www.google.com"
}
]
I am familiar with parsing json having the title object, but i've no clue about how to parse the above json as it is missing the title object. Can you please provide me with some hints/examples so i can check them and work on parsing the above code?
Note : I've checked a similar example here but it doesn't have a satisfactory solution.
Your JSON is an array of objects.
The whole idea around Gson (and other JSON serialization/deserialization) libraries is that you wind up with your own POJOs in the end.
Here's how to create a POJO that represents the object contained in the array and get a List of them from that JSON:
public class App
{
public static void main( String[] args )
{
String json = "[{\"title\":\"facebook\",\"description\":\"social networking website\"," +
"\"url\":\"http://www.facebook.com\"},{\"title\":\"WoW\",\"description\":\"game\"," +
"\"url\":\"http://us.battle.net/wow/\"},{\"title\":\"google\",\"description\":\"search engine\"," +
"\"url\":\"http://www.google.com\"}]";
// The next 3 lines are all that is required to parse your JSON
// into a List of your POJO
Gson gson = new Gson();
Type type = new TypeToken<List<WebsiteInfo>>(){}.getType();
List<WebsiteInfo> list = gson.fromJson(json, type);
// Show that you have the contents as expected.
for (WebsiteInfo i : list)
{
System.out.println(i.title + " : " + i.description);
}
}
}
// Simple POJO just for demonstration. Normally
// these would be private with getters/setters
class WebsiteInfo
{
String title;
String description;
String url;
}
Output:
facebook : social networking website
WoW : game
google : search engine
Edit to add: Because the JSON is an array of things, the use of the TypeToken is required to get to a List because generics are involved. You could actually do the following without it:
WebsiteInfo[] array = new Gson().fromJson(json, WebsiteInfo[].class);
You now have an array of your WebsiteInfo objects from one line of code. That being said, using a generic Collection or List as demonstrated is far more flexible and generally recommended.
You can read more about this in the Gson users guide
JSONArray jsonArr = new JSONArray(jsonResponse);
for(int i=0;i<jsonArr.length();i++){
JSONObject e = jsonArr.getJSONObject(i);
String title = e.getString("title");
}
use JSONObject.has(String name) to check an key name exist in current json or not for example
JSONArray jsonArray = new JSONArray("json String");
for(int i = 0 ; i < jsonArray.length() ; i++) {
JSONObject jsonobj = jsonArray.getJSONObject(i);
String title ="";
if(jsonobj.has("title")){ // check if title exist in JSONObject
String title = jsonobj.getString("title"); // get title
}
else{
title="default value here";
}
}
JSONArray array = new JSONArray(yourJson);
for(int i = 0 ; i < array.lengh(); i++) {
JSONObject product = (JSONObject) array.get(i);
.....
}
As the title says really. I have two columns. I want to put them into textviews so I did it. However only the bottom two results, one from each column gets shown. Very odd. Here is my code: http://pastebin.com/qNgfHfT3
The parsing/onPostExecute is towards the bottom where the issue is.
One thing to note: The logs labeled "work" & "dontwork" show all my results, however the logs in the onPostExecute (Google & Google1) only show the last result so I presume the error is in the transfer from parsing to displaying.
Would really appreciate any help here. Thanks.
If you are receiving a JSON response I'd suggest you to parse it by using Gson. It's strongly recommendable as long as you can parse the whole thing in a pair of lines.
Note that creating a proper object it is as easy as doing the following:
YourObject object = gson.fromJson(responseReader, YourObject.class);
or even if you are retrieving a list of items:
Type listType = new TypeToken<List<YourObject>>() {}.getType();
List<YourObject> objects = gson.fromJson(responseReader, listType);
Here's an example that fits exactly your needs
After the process is done you'll have your object (or list of objects) available in an accesible variable.
EDIT:
First your Asynctask should have the following params:
public class HttpTask extends AsyncTask<Void, Void, ArrayList<Driver>> {
and your doInBackground method will need to pass that array to your onPostExecute:
#Override
protected ArrayList<Driver> doInBackground(Void... params) {
For the rest, I take it when the JSon parsing starts.
//PARSING JSON DATA
try {
JSONObject json_data;
Driver d;
jArray = new JSONArray(result);
int l = jArray.length();
if(l>0){
ArrayList<Driver> drivers = newArrayListList<Driver>();
for (int i = 0; i < l; i++) {
json_data = jArray.getJSONObject(i);
d = new Driver(json_data.optString("Driver_full_name"), json_data.optString("Drives_for"));
drivers.add(d);
Log.i("work", returnString);
Log.i("dontwork", somethingelse);
}
} catch (JSONException e1) {
Log.d("DB", "Error somewhere");
CurrentSeasonDrivers_DriverName.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(CurrentSeasonDrivers_DriversName, "Could not parse data so shut up", Toast.LENGTH_LONG).show();
}
});
}
return drivers;
}
protected void onPostExecute(ArrayList<Drivers>... drivers) {
Log.i("Google", returnString);
Log.i("Google1", somethingelse);
String firstDriverName = drivers.get(0).name;
String firstDriverDrivesFor = drivers.get(0).drivesfor;
String secondDriverName = drivers.get(1).name;
TextView drivername = (TextView) findViewById(R.id.DriverName);
drivername.setText(firstDriverName);
TextView drivesfor = (TextView) findViewById(R.id.DrivesFor);
drivesfor.setText(firstDriverDrivesFor);
}
With this and an object for your driver will complete the circle.
public class Driver{
public String name;
public String drivesfor;
public Driver(String _name, String _drivesfor){
name = _name;
drivesfor = _drivesfor;
}
}
I guess you can take over from here.
Let me know about your progress.
I have a JSON string such as below. That comes from a Website (the URL outputs below to a page) which I'm using in an android application.
{"posts": [{"id":"0000001","longitude":"50.722","latitude":"-1.87817","position":"Someplace 1","altitude":"36","description":"Some place 1 "},{"id":"0000002","longitude":"50.722","latitude":"-1.87817","position":"Some PLace 2","altitude":"36","description":"Some place 2 description"}]}
I would like to deserialize this into a List where I can iterate through them later on the application. How do I do this? I have created a class with properties and methods and a List class as below and then using fromJson to deserialize it, but it returns NULL. Hope the question is clear and many thanks in advance.
ListClass
package dataaccess;
import java.util.List;
public class LocationList {
public static List<Location> listLocations;
public void setLocationList(List <Location> listLocations) {
LocationList.listLocations = listLocations;
}
public List<Location> getLocationList() {
return listLocations;
}
}
GSON
public LocationList[] getJsonFromGson(String jsonURL) throws IOException{
URL url = new URL(jsonURL);
String content = IOUtils.toString(new InputStreamReader(url.openStream()));
LocationList[] locations = new Gson().fromJson(content, LocationList[].class);
return locations;
}
You try to deserialize into an array of LocationList objects - that surely wasn't your intent, was it? The json snippet doesn't contain a list of lists.
I would drop the class LocationList (except it ought to be extened in future?), and use a pure List. Then, you have to create a type token like this:
java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<ArrayList<Location>>() {}.getType();
List<Location> locations = new Gson().fromJson(content, type);
What if this JSON response can be parsed using native classes, here is a solution for the same:
String strJsonResponse="Store response here";
JsonObject obj = new JsonObject(strJsonResponse);
JsonArray array = obj.getJsonArray("posts");
for(int i=0; i<array.length; i++)
{
JsonObject subObj = array.getJsonObject(i);
String id = subObj.getString("id");
String longitude = subObj.getString("longitude");
String latitude = subObj.getString("latitude");
String position = subObj.getString("position");
String altitude = subObj.getString("altitude");
String description = subObj.getString("description");
// do whatever procedure you want to do here
}