【问题标题】:nested json parsing for android with jackson使用jackson对android进行嵌套json解析
【发布时间】:2013-02-16 18:09:43
【问题描述】:

我刚开始使用 android 编程并通过使用 imdb api 找到了不错的教程。而不是在本教程中使用 xml 我想使用 json 并且对于收到的 json 我有问题。 这是 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"
}
]

我的两个对象:

    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;   
    }

我不知道如何使用杰克逊对象映射器检索人员列表。 当我使用这个时:

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

我明白了:

02-16 18:34:48.010: W/System.err(376): com.fasterxml.jackson.databind.JsonMappingException: 无法反序列化 com.example.imdbsearcher.model.Person 的实例超出 START_ARRAY 令牌 02-16 18:34:48.180: W/System.err(376): 在 [来源: java.io.StringReader@40a81778;行:1,列:1] 02-16 18:34:48.554: W/System.err(376): 在 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)

在 Keith 和 crdnilfan 的建议下,我更改了检索方法。 但是现在我对profile的属性有问题。

我意识到我缺少那个人对象,基本上我已经创建了新的配置文件对象并将 imageList 移动到这个类。

我已经更新了上面的 POJO。

但现在我在配置文件中遇到了同样的错误。

无法从 START_ARRAY 令牌中反序列化 com.example.imdbsearcher.model.Profile 的实例

【问题讨论】:

  • 请发布完整的堆栈跟踪。
  • 我已在我的答案中添加了该类的修改版本

标签: android json jackson


【解决方案1】:

您需要反序列化列表,因为您的 JSON 是一个数组:

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

但是,在您这样做之后,由于 JSON 中的配置文件属性,您会遇到一些额外的反序列化错误。结帐:http://jackson.codehaus.org/1.5.7/javadoc/org/codehaus/jackson/annotate/JsonIgnoreProperties.html

更新:

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;
}

有几种方法可以解决这个问题。这将为您提供 Profile 的链接哈希映射。

或者,如果您控制 JSON 格式,请将配置文件语法更改为:

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

【讨论】:

  • 谢谢 keith,但我仍然无法在这个映射中弄清楚,jackson 将如何映射图像属性?
  • 好的,我认为这将是我的公共 List 个人资料,不是吗?
  • 您的 JSON 仅包含“图像”属性的单个对象,而不是 JSON 数组。所以它应该只是Image 对象。
【解决方案2】:

那是因为您试图反序列化 Person.class 列表,而不是一个实例。像这样创建另一个类

public class PersonList extends ArrayList<Person> {}

然后使用

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

【讨论】:

  • 那个,或者映射到数组:Person[] people = mapper.readValue(jsonResponseString, Person[].class);(数组非常好,因为它们是强类型的,没有泛型)
【解决方案3】:

另外两个答案清楚地解释了错误的原因,它将摆脱错误并解析 Person 对象。但对我来说,它无法解析图像对象。使用下面的 POJO,我们可以完全解析指定的 json,即使没有

@JsonIgnoreProperties

or 

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

POJO 定义:

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;

}

这应该解析 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多