有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用GSON时发生java非法状态异常

我正在尝试读取以下JSON文件:

{ "rss" : {
     "@attributes" : {"version" : "2.0" },
      "channel" : { 
          "description" : "Channel Description",
          "image" : { 
              "link" : "imglink",
              "title" : "imgtitle",
              "url" : "imgurl"
            },

          "item" : {
              "dc_format" : "text",
              "dc_identifier" : "link",
              "dc_language" : "en-gb",
              "description" : "Description Here",
              "guid" : "link2",
              "link" : "link3",
              "pubDate" : "today",
              "title" : "Title Here"
            },

          "link" : "channel link",
          "title" : "channel title"
        }
    } 
}

进入该对象:

public class RSSWrapper{
    public RSS rss;

    public class RSS{
        public Channel channel;
    }

    public class Channel{
        public List<Item> item;

    }
    public class Item{
        String description;//Main Content
        String dc_identifier;//Link
        String pubDate;
        String title;

    }
}

我只想知道“item”对象中有什么,所以我假设上面的类在调用时可以工作:

Gson gson = new Gson();
RSSWrapper wrapper = gson.fromJson(JSON_STRING, RSSWrapper.class);

但是我得到了一个错误:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT

我真的不知道这意味着什么,所以我不知道在哪里可以找到错误,希望对GSON有更好了解的人可以帮助我

谢谢:)


共 (2) 个答案

  1. # 1 楼答案

    您的JSON字符串和RSSWrapper类不兼容:Channel希望有一个List<Item>,而JSON字符串包含一个项。您必须将Channel修改为:

    public class Channel{
        public Item item;
    
    }
    

    或者JSON作为:

    "item" : [{
        "dc_format" : "text",
        "dc_identifier" : "link",
        "dc_language" : "en-gb",
        "description" : "Description Here",
        "guid" : "link2",
        "link" : "link3",
        "pubDate" : "today",
        "title" : "Title Here"
    }],
    

    指示它是一个包含一个元素的数组

  2. # 2 楼答案

    如果控制JSON输入的外观,最好将item更改为JSON数组

    "item" : [{
        "dc_format" : "text",
        "dc_identifier" : "link",
        "dc_language" : "en-gb",
        "description" : "Description Here",
        "guid" : "link2",
        "link" : "link3",
        "pubDate" : "today",
        "title" : "Title Here"
    }]
    

    如果您不这样做,并且希望您的程序能够处理item数组或具有相同RSSWrapper类的对象;这里有一个程序化的解决方案

    JSONObject jsonRoot = new JSONObject(JSON_STRING);
    JSONObject channel = jsonRoot.getJSONObject("rss").getJSONObject("channel");
    
    System.out.println(channel);
    if (channel.optJSONArray("item") == null) {
        channel.put("item", new JSONArray().put(channel.getJSONObject("item")));
        System.out.println(channel);
    }
    
    Gson gson = new Gson();
    RSSWrapper wrapper = gson.fromJson(jsonRoot.toString(), RSSWrapper.class);
    
    System.out.println(wrapper.rss.channel.item.get(0).title); // Title Here
    

    使用Java org.json解析器,代码通过将JSONObject包装到数组中来简单地替换它。如果item已经是一个JSONArray,它会保持JSON_STRING不变