Android上的深度JSON解析

时间:2014-04-02 09:57:35

标签: android json parsing jackson

我有这个JSON提要解析:

 {
"movies": [{
    "id": "770810965",
    "title": "Invictus",
    "year": 2009,
    "mpaa_rating": "PG-13",
    "runtime": 134,
    "critics_consensus": "Delivered with typically stately precision from director Clint Eastwood, Invictus may not be rousing enough for some viewers, but Matt Damon and Morgan Freeman inhabit their real-life characters with admirable conviction.",
    "release_dates": {
        "theater": "2009-12-11",
        "dvd": "2010-05-18"
    },
    "ratings": {
        "critics_rating": "Certified Fresh",
        "critics_score": 76,
        "audience_rating": "Upright",
        "audience_score": 75
    },
    "synopsis": "",
    "posters": {
        "thumbnail": "http://content7.flixster.com/movie/10/92/27/10922777_mob.jpg",
        "profile": "http://content7.flixster.com/movie/10/92/27/10922777_pro.jpg",
        "detailed": "http://content7.flixster.com/movie/10/92/27/10922777_det.jpg",
        "original": "http://content7.flixster.com/movie/10/92/27/10922777_ori.jpg"
    },
    "abridged_cast": [{
        "name": "Morgan Freeman",
        "id": "162652224",
        "characters": ["Nelson Mandela"]
    }, {
        "name": "Matt Damon",
        "id": "162653499",
        "characters": ["Francois Pienaar"]
    }, {
        "name": "Tony Kgoroge",
        "id": "528345122",
        "characters": ["Jason Tshabalala"]
    }, {
        "name": "Patrick Mofokeng",
        "id": "770837270",
        "characters": ["Linga Moonsamy"]
    }, {
        "name": "Matt Stern",
        "id": "770867648",
        "characters": ["Hendrick Booyens"]
    }],
    "alternate_ids": {
        "imdb": "1057500"
    },
    "links": {
        "self": "http://myProjectmobiletest.herokuapp.com/api/public/v1.0/movies/770810965.json",
        "alternate": "http://www.rottentomatoes.com/m/invictus/",
        "cast": "http://myProjectmobiletest.herokuapp.com/api/public/v1.0/movies/770810965/cast.json",
        "clips": "http://myProjectmobiletest.herokuapp.com/api/public/v1.0/movies/770810965/clips.json",
        "reviews": "http://myProjectmobiletest.herokuapp.com/api/public/v1.0/movies/770810965/reviews.json",
        "similar": "http://myProjectmobiletest.herokuapp.com/api/public/v1.0/movies/770810965/similar.json"
    }
},

我检索字段标题和概要如下:

 try{
        jsonResponse = new JSONObject(response);
        JSONArray jsonTitleNode = jsonResponse.optJSONArray("movies");
        lengthJsonArr = jsonTitleNode.length();

        for(int i = 0; i < lengthJsonArr; i++){
            JSONObject jsonChildNode = jsonTitleNode.getJSONObject(i);
            movieTitle = jsonChildNode.optString("title").toString();
            movieSynopsis = jsonChildNode.optString("synopsis").toString();
            mListTitle.add(movieTitle);
            mListSynopsis.add(movieSynopsis);
        }
    }

mListTitle和mListSynopsis包含我想要的列表并且效果很好。现在,我想在我的JSON数组中检索一些更深的字段,如&#34; name&#34; &#34; abridget_cast&#34;中的演员节点和最后一个字段&#34;类似&#34;。如果你能帮助我做到这一点,谢谢你。

2 个答案:

答案 0 :(得分:2)

试试这个..

try{

    jsonResponse = new JSONObject(response);
    JSONArray jsonTitleNode = jsonResponse.optJSONArray("movies");
    lengthJsonArr = jsonTitleNode.length();

    for(int i = 0; i < lengthJsonArr; i++){
        JSONObject jsonChildNode = jsonTitleNode.getJSONObject(i);
        movieTitle = jsonChildNode.optString("title").toString();
        movieSynopsis = jsonChildNode.optString("synopsis").toString();
        mListTitle.add(movieTitle);
        mListSynopsis.add(movieSynopsis);

        JSONArray jsoncastarray = jsonChildNode.optJSONArray("abridged_cast");
        for(int j = 0; j < jsoncastarray.length(); j++){
            JSONObject jsoncast = jsoncastarray.getJSONObject(j);
            Log.v("name--",""+jsoncast.optString("name").toString());
            Log.v("id--",""+jsoncast.optString("id").toString());
            JSONArray chararray = jsoncast.optJSONArray("characters");
            for(int k = 0; k < chararray.length(); k++){
                  Log.v("char--",""+chararray.optString(k).toString());
            }
        }
    }
}

<强> EDIT1:

HashMap<String, ArrayList<String>> new_values = new HashMap<String, ArrayList<String>>();
new_values.put(movie id,arraylist of actors name);

编辑2:

HashMap<String, ArrayList<String>> new_values = new HashMap<String, ArrayList<String>>();
ArrayList<String> id_list = new ArrayList<String>();
for(int i = 0; i < lengthJsonArr; i++){         
     id_list.add(""+jsonChildNode.optString("id").toString());
     ArrayList<String> actors_list = new ArrayList<String>();
     for(int j = 0; j < jsoncastarray.length(); j++){
         actors_list.add(""+jsoncast.optString("name").toString());
     }
     new_values.put(""+jsonChildNode.optString("id").toString(),actors_list);
}

编辑3:

for (Map.Entry<String,ArrayList<String>> entry : new_values.entrySet()) {
       Log.v("Id",""+entry.getKey());
       Log.v("actors_list",""+entry.getValue());
}

编辑4:

for(int i = 0; i < lengthJsonArr; i++){
            JSONObject jsonChildNode = jsonMovieNode.getJSONObject(i);
            movieTitle = jsonChildNode.optString(Constants.TAG_TITLE).toString();
            movieSynopsis = jsonChildNode.optString(Constants.TAG_SYNOPSIS).toString();
            id_list.add("" + jsonChildNode.optString("id").toString());
            mListTitle.add(movieTitle);
            mListSynopsis.add(movieSynopsis);

            actors_list = new ArrayList<String>();
            JSONArray jsonCastArray = jsonChildNode.optJSONArray("abridged_cast");
            for(int j = 0; j < jsonCastArray.length(); j++){
            try{
                JSONObject jsonCast = jsonCastArray.getJSONObject(j);
                movieCasting = jsonCast.optString("name").toString();
                actors_list.add(""+jsonCast.optString("name").toString());
                new_values.put(""+jsonChildNode.optString("id").toString(),actors_list);
                mListCasting.add(movieCasting);
            }
            catch (Exception e){}
            }
        }

编辑5:

            Intent detailIntent = new Intent(MovieActivity.this, DetailActivity_.class);
            Bundle bundle = new Bundle();
            bundle.putString("title", mListTitle.get(position));
            bundle.putString("synopsis", mListSynopsis.get(position));
            detailIntent.putStringArrayListExtra("casting", actors_list);
            detailIntent.putExtras(bundle);
            startActivity(detailIntent);

答案 1 :(得分:2)

使用库可能会更好:Gson可以映射数据和模型类。例如:

Gson gson = new Gson();
ModelClass modelClass= new ModelClass();
modelClass= gson.fromJson(responseContent,ModelClass.class); 
//where responseContent is your jsonString
    Log.i("Web service response", ""+modelClass.toString());

https://code.google.com/p/google-gson/

对于命名差异(根据webservice中的变量),可以使用@SerializedName之类的注释。 (所以不需要使用Serializable)

这样你就可以在对象中获得所有数据。无需手动解析它。

根据响应,您的模型类可能类似于:

public class Movies {

String id;  
String title;  
Posters posters;  
// other fields & getter,setter
}

public class Posters{
String thumbnail;
//other fields
}

可以使用a为每个循环解析多个对象,然后检索您的字段值 http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
How does the Java 'for each' loop work?

这样,由于你有一个精心设计的json响应,你不需要编写代码来解析它并手动检索字段,你可以选择在类中命名字段(可以排除那些字段)你不需要)。然后,您可以使用其对象。