java - 使用 Gson 库解析 Json

标签 java android json gson

您好,我无法弄清楚如何使用 Java 中的 Gson 库创建对象。 我遵循了一些在线指南 Link To One Here他们说必须将 Json 结构的每个部分创建为类,就像我所做的那样,但在创建对象时我仍然得到 null 值。

Nodes nodes = gson.fromJson(obj.get("Nodes"), Nodes.class);

nodes 给了我一个空值。

如果有人可以帮助我指出我缺少什么或者我是否错误地创建了我的类,那将会有很大的帮助。

这是我想要解析并创建对象的 JSON 结构:

{
"nodes":[
{
"node":{
"image_thumb":"/sites/all/themes/imsa/images/headlines-thumb.png",
"body_image":" <p>Test</p>\n ",
"title":"Test",
"link":"<a href=\"/articles/test\">view</a>",
"updated":"2013-11-12 11:52",
"body":"<p>Test</p>",
"type":"Article"
}
},
{
"node":{
"image_thumb":"/sites/all/themes/imsa/images/headlines-thumb.png",
"body_image":" <p>test</p>\n ",
"title":"Test Event",
"link":"<a href=\"/articles/test-event\">view</a>",
"updated":"2013-11-08 17:56",
"body":"<p>test</p>",
"type":"Article"
}
},
{
"node":{
"image_thumb":"/sites/all/themes/imsa/images/headlines-thumb.png",
"body_image":" <p>Atricle with no image</p>\n ",
"title":"No Image",
"link":"<a href=\"/articles/no-image\">view</a>",
"updated":"2013-11-01 16:39",
"body":"<p>Atricle with no image</p>",
"type":"Article"
}
},
{
"node":{
"image_thumb":"/sites/default/files/styles/square_thumbnail/public/field/image/test_cars_1.jpg",
"image_medium":"/sites/default/files/styles/media_gallery_thumbnail/public/field/image/test_cars_1.jpg",
"body_image":" <p style=\"text-align: justify; font-size: 11px; line-height: 14px; margin-bottom: 14px; font-family: Arial, Helvetica, sans;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur dapibus massa vitae mauris elementum dignissim. Etiam ut cursus nulla, at accumsan lacus. Vivamus semper massa ut lorem pulvinar, et porta magna commodo. Quisque tempus ligula eget nisi condimentum lobortis. Praesent in tincidunt massa. Fusce eleifend interdum justo a malesuada. Pellentesque eget condimentum mi, sed congue enim.</p>\n<p style=\"text-align: justify; font-size: 11px; line-height: 14px; margin-bottom: 14px; font-family: Arial, Helvetica, sans;\">Nam ornare pretium volutpat. Sed vitae dolor odio. Cras eleifend tellus at ultrices vehicula. Aenean luctus auctor hendrerit. Nullam egestas at lectus sed scelerisque. Aenean nec sagittis tellus. Aenean nec nibh non erat pellentesque hendrerit id sed quam. Phasellus id dapibus metus. Nunc ultricies enim vitae aliquet semper. Fusce eu mollis elit.</p>\n ",
"title":"Testing it Up",
"subtitle":"As we do",
"link":"<a href=\"/articles/testing-it\">view</a>",
"updated":"2013-10-31 13:31",
"body":"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur dapibus massa vitae mauris elementum dignissim. Etiam ut cursus nulla, at accumsan lacus. Vivamus semper massa ut lorem pulvinar, et porta magna commodo. Quisque tempus ligula eget nisi condimentum lobortis. Praesent in tincidunt massa. Fusce eleifend interdum justo a malesuada. Pellentesque eget condimentum mi, sed congue enim.</p><p>Nam ornare pretium volutpat. Sed vitae dolor odio. Cras eleifend tellus at ultrices vehicula. Aenean luctus auctor hendrerit. Nullam egestas at lectus sed scelerisque. Aenean nec sagittis tellus. Aenean nec nibh non erat pellentesque hendrerit id sed quam. Phasellus id dapibus metus. Nunc ultricies enim vitae aliquet semper. Fusce eu mollis elit.</p>",
"type":"Article"
}
}
]
}

这是我创建的一个类,它发出http请求以返回Json数据,并尝试使用这里的Gson库根据返回的Json结构创建一个对象。

private class NewsAsyncTask extends AsyncTask<Void, Void, Void> {

@Override
protected Void doInBackground(Void... params) {
    String url = "http://imsa.com/series/united-sportscar/news.json/";
    HttpGet getRequest = new HttpGet(url);

    try{
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpResponse getResponse = httpClient.execute(getRequest);
        final int statusCode = getResponse.getStatusLine().getStatusCode();

        if(statusCode != HttpStatus.SC_OK) {
            Log.w(getClass().getSimpleName(), "Error " + statusCode + " for URL " + url);
        }

        HttpEntity getResponseEntity = getResponse.getEntity();
        InputStream httpResponseStream = getResponseEntity.getContent();
        InputStreamReader inputStreamReader = new InputStreamReader(httpResponseStream);

        JsonParser parser = new JsonParser();
        JsonObject obj = parser.parse(inputStreamReader).getAsJsonObject();


        Gson gson = new Gson();
        Nodes nodes = gson.fromJson(obj.get("Nodes"), Nodes.class);
        System.out.println(nodes.getNews());
    }
    catch (IOException e) {
        getRequest.abort();
        Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
    }

    return null;
}

以下是我使用的构成我要解析的 Json 结构的所有类:

节点类 -

public class Nodes implements Serializable {

    @SerializedName("nodes")
    private final ArrayList<News> news;

    public Nodes(final ArrayList<News> news) {
        this.news = news;
    }

    public Nodes(final Nodes nodesToCopy) {
        this.news = nodesToCopy.getNews();
    }

    public ArrayList<News> getNews() {
        return news;
    }

    @Override
    public String toString() {
        return "Nodes{" +
                "news=" + news +
                '}';
    }
}

新闻类 -

public class News {

    @SerializedName("node")
    ArrayList<NewsItem> news;

    public News(ArrayList<NewsItem> news) {
        this.news = news;
    }

    public ArrayList<NewsItem> getNews() {
        return news;
    }

    @Override
    public String toString() {
        return "News{" +
                "news=" + news +
                '}';
    }
}

NewsItem 类 -

public class NewsItem implements Serializable {

    @SerializedName("image_thumb")
    private final String imageThumb;

    @SerializedName("image_medium")
    private final String imageMedium;

    @SerializedName("body_image")
    private final String bodyImage;

    @SerializedName("title")
    private final String title;

    @SerializedName("link")
    private final String link;

    @SerializedName("updated")
    private final Date updated;

    @SerializedName("body")
    private final Text body;

    @SerializedName("type")
    private final String type;

    public NewsItem(String imageThumb, String imageMedium, String bodyImage, String title, String link, Date updated, Text body, String type) {
        this.imageThumb = imageThumb;
        this.imageMedium = imageMedium;
        this.bodyImage = bodyImage;
        this.title = title;
        this.link = link;
        this.updated = updated;
        this.body = body;
        this.type = type;
    }

    public NewsItem(final NewsItem newsItemToCopy) {
        this.imageThumb = newsItemToCopy.getImageThumb();
        this.imageMedium = newsItemToCopy.getImageMedium();
        this.bodyImage = newsItemToCopy.getBodyImage();
        this.title = newsItemToCopy.getTitle();
        this.link = newsItemToCopy.getLink();
        this.updated = newsItemToCopy.getUpdated();
        this.body = newsItemToCopy.getBody();
        this.type = newsItemToCopy.getType();
    }

    public String getImageThumb() {

        return imageThumb;
    }

    public String getImageMedium() { return imageMedium; }

    public String getBodyImage() {
        return bodyImage;
    }

    public String getTitle() {
        return title;
    }

    public String getLink() {
        return link;
    }

    public Date getUpdated() {
        return updated;
    }

    public Text getBody() {
        return body;
    }

    public String getType() {
        return type;
    }

    @Override
    public String toString() {
        return "NewsItem{" +
                "imageThumb='" + imageThumb + '\'' +
                ", imageMedium='" + imageMedium + '\'' +
                ", bodyImage='" + bodyImage + '\'' +
                ", title='" + title + '\'' +
                ", link='" + link + '\'' +
                ", updated=" + updated +
                ", body=" + body +
                ", type='" + type + '\'' +
                '}';
    }
}

最佳答案

这里有很多问题,但修复起来相对容易。

第一

JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(inputStreamReader).getAsJsonObject();

obj 现在包含完整的 JSON。所以当你这样做时

obj.get("Nodes")

您将在整个 JSON 中获取名为 nodes 的数组对象。但您的 Nodes 类需要它。所以Gson不会找到任何东西并且会返回null。您需要将 obj 直接提供给 fromJson 调用。

其次,每个node元素都是一个JSON对象

"node":{
"image_thumb":"/sites/all/themes/imsa/images/headlines-thumb.png",
"body_image":" <p>Test</p>\n ",
"title":"Test",
"link":"<a href=\"/articles/test\">view</a>",
"updated":"2013-11-12 11:52",
"body":"<p>Test</p>",
"type":"Article"
}

不是 JSON 数组。因此这个

@SerializedName("node")
ArrayList<NewsItem> news;

是错误的。 ArrayList 采用数组结构,而不是单个元素。将其(以及修改器/访问器)更改为

@SerializedName("node")
NewsItem news;

最后,您还没有设置 Date 格式,因此 Gson 不知道如何反序列化

"2013-11-12 11:52"

转换为Date对象。您可以设置自己的 Date 格式并获取正确配置的 Gson 对象,如下所示

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm").create();

关于java - 使用 Gson 库解析 Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20600471/

相关文章:

json - Gson 可选和必填字段

java - 如何将Java对象转换为JSON

java - 如何使 "MessageDigest SHA-1 and Signature NONEwithRSA"等同于 "Signature SHA1withRSA "

java - 如何传输参数到重定向jsp,该参数可以访问到该jsp

java - 具有多种消息类型的 Kafka 和主题 (Avro) : Consumer(spring cloud spring fails due to the lack of class on classpath

php - 如何从MySQL数据库中检索特定用户数据并显示在 ListView 中?

Android-Volley : set HTTP Header for JsonArrayRequest

java - Android 登录屏幕无法正常工作

android - 以编程方式生成 View 并捕获位图

android - 使用 fragment 内的recyclerview在滚动时隐藏工具栏