简体   繁体   中英

nested json parsing for android with jackson

i just started to android prograamming and found nice tutorial by using imdb api. instead of using xml in this tutorial i would like to use json and for the recevied json i have a problem. this is the person.json:

    [
        {
    "score":1,
    "popularity":3,
    "name":"Brad Pitt",
    "id":287,
    "biography":"test",
    "url":"http://www.themoviedb.org/person/287",
    "profile":[
        {
            "image":{
                "type":"profile",
                "size":"thumb",
                "height":68,
                "width":45,
                "url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w45/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
                "id":"4ea5cb8c2c0588394800006f"
            }
        },
        {
            "image":{
                "type":"profile",
                "size":"profile",
                "height":281,
                "width":185,
                "url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
                "id":"4ea5cb8c2c0588394800006f"
            }
        },
        {
            "image":{
                "type":"profile",
                "size":"h632",
                "height":632,
                "width":416,
                "url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/h632/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
                "id":"4ea5cb8c2c0588394800006f"
            }
        },
        {
            "image":{
                "type":"profile",
                "size":"original",
                "height":1969,
                "width":1295,
                "url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/original/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
                "id":"4ea5cb8c2c0588394800006f"
            }
        }
    ],
    "version":685,
    "last_modified_at":"2013-02-16 07:11:15 UTC"
}
]

my two object for them:

    public class Person implements Serializable {

   private static final long serialVersionUID = 6794898677027141412L;

   public String score;
   public String popularity;
   public String name;
   public String id;
   public String biography;
   public String url;
   public String version;
   public String lastModifiedAt;
   public Profile profile;
    }

    public class Profile implements Serializable {

   private static final long serialVersionUID = -8735669377345509929L;

   public ArrayList<Image> imagesList;

    }

    public class Image implements Serializable {

   private static final long serialVersionUID = -2428562977284114465L;

   public String type;
   public String url;
   public String size;
   public int width;
   public int height;   
    }

ı couldnt figure out how to retrieve person list by using jackson object mapper. when i use this one:

    ObjectMapper mapper = new ObjectMapper();
    Person person= mapper.readValue(jsonResponseString, Person.class);

i got:

02-16 18:34:48.010: W/System.err(376): com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.example.imdbsearcher.model.Person out of START_ARRAY token 02-16 18:34:48.180: W/System.err(376): at [Source: java.io.StringReader@40a81778; line: 1, column: 1] 02-16 18:34:48.554: W/System.err(376): at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599) 02-16 18:34:48.830: W/System.err(376): at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:593)

i have changed the retrieve method with advice of Keith and crdnilfan. but now i have a problem with the attribute of profile.

i realized that i am missing that one in person object and basicly i have created new profile object and moved imageList to this class.

i have updated POJO's as above.

but now i am getting the same error for the profile.

Can not deserialize instance of com.example.imdbsearcher.model.Profile out of START_ARRAY token

That's because you are trying to deserialize a list of Person.class, not one instance. Create another class like this

public class PersonList extends ArrayList<Person> {}

and then use

ArrayList<Person> people = mapper.readValue(jsonResponseString, PersonList.class);

You need to deserialize the list, as your JSON is an array:

List<Person> people = mapper.readValue(
                      jsonResponseString, new TypeReference<List<Person >>(){});

However, after you do that you will have some additional deserialization errors because of the profile property in your JSON. Checkout: http://jackson.codehaus.org/1.5.7/javadoc/org/codehaus/jackson/annotate/JsonIgnoreProperties.html

Update:

public class Person implements Serializable 
{

  public List<Object> profile;

  public String score;
  public String popularity;
  public String name;
  public String id;
  public String biography;
  public String url;
  public String version;
  public String last_modified_at;
}

There are several ways to deal with this. This will give you a linked hash map for Profile.

Alternatively, if you control the JSON format, change the profile syntax to this:

"profile":[
      image:...,
      image:...
 ]

The other two answers clearly explain the reason for the error, it would get rid off the error and it will parse Person object. But for me it failed to parse image objects. With below POJO we can parse the specified json completely, without any issues even in the absence of

@JsonIgnoreProperties

or 

mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

POJO definition:

public  class PersonList extends ArrayList<Person> {}

public class Person implements Serializable {

    private static final long serialVersionUID = 6794898677027141412L;

    public String score;
    public String popularity;
    public String name;
    public String id;
    public String biography;
    public String url;
    public String version;
    @JsonProperty(value="last_modified_at")
    public String lastModifiedAt;

    public List<Profile> profile;

}

public class Profile implements Serializable {

private static final long serialVersionUID = -8735669377345509929L;
    @JsonProperty(value="image")
    public Image imagesList;

 }

public class Image implements Serializable {

    private static final long serialVersionUID = -2428562977284114465L;

    public String id;
    public String type;
    public String url;
    public String size;
    public int width;
    public int height;

}

This should parse the json

String jsonResponseString = readJsonFile("person.json"); 
ObjectMapper mapper = new ObjectMapper();

PersonList person= mapper.readValue(jsonResponseString, PersonList.class);
       or
List<Person> person= mapper.readValue(jsonResponseString, 
new TypeReference<List< Person>>(){}); //if we use this we dont have to define PersonList class

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM